由dll導出的lib文件: 包含了每一個dll導出函數的符號名和可選擇的標識號以及dll文件名,不含有實際的代碼(這里的lib文件和靜態庫是不一樣的),其中的導出導入函數都 是跳轉指令,直接跳轉到DLL中的位置。基於這樣一句話可以看出在編譯一個程序的時候,編譯器先通過頭文件知道要使用函數的格式,然后在lib文件中(這 里的lib文件名是可以隨便更換的)查找這個函數在dll文件中的具體地址,從而知道這個函數的入口點。其次由於lib包含了dll文件名,所以在執行 exe程序的時候,dll文件的名稱是不能更改的。
一、生成DLL
1. 新建DLL工程
生成DLL可以多種方法,這里介紹一種。在VS中,新建一個空的項目,選Win32 Console Application,新建完后修改工程屬性:把生成EXE改為生成DLL
2. 源代碼:
ShowInfo.h
- #ifdef SHOWINFO_EXPORTS
- #define SHOWINFO_API __declspec(dllexport)
- #else
- #define SHOWINFO_API __declspec(dllimport)
- #endif
- extern "C" SHOWINFO_API void fnShowInfo(void);
ShowInfo.c:
- #define SHOWINFO_EXPORTS
- #include "ShowInfo.h"
- #include <stdio.h>
- SHOWINFO_API void fnShowInfo(void)
- {
- printf("Crab\n");
- }
3. 編譯連接,生成dll.dll文件
ps:
1. 特別要注意要在ShowInfo.c文件的開頭加上#define SHOWINFO_EXPORTS
2. 在ShowInfo.h中聲明函數的時候要加上 extern "C", 因為如果該函數可能會被c++ 程序調用。
二、 使用DLL
1. 新建工程
新建一個Win32 Console Application,選擇空的工程。
2. 源代碼:
main.cpp
#include <windows.h>
#include <iostream>
using namespace std;
typedef
int main()
{
HINSTANCE hInst = LoadLibrary(TEXT("ShowInfo.dll"));
if(hInst)
{
DllFn a =(DllFn) GetProcAddress(hInst,"fnShowInfo");
if(a)
a();
else
cout<<"ERROR on GetProcAddress"<<endl;
FreeLibrary(hInst);
}
else
cout<<"Error on Load library"<<endl;
}
ps:
a. 用 LoadLibrary 可能會出現 “不能將參數 1 從‘const char [13]’轉換為‘LPCWSTR’”的錯誤,這時需要用到TEXT()函數。
b. 由於用了LoadLibrary函數,所以dll的文件名可以改變,只要文件名和LoadLibrary中的參數一樣,就可以了。
3. 將上面工程生成的dll.dll文件復制到此工程的目錄下,保證源文件與DLL文件在同一目錄下。如果生成的EXE文件要直接運行,則要保證EXE文件與DLL文件在同一目錄下。
4. 編譯連接,執行。