dll的动态加载
dll的加载方式有两种:隐式链接和动态加载。隐式链接,需要包含头文件,引用.lib文件才能使用导出函数。动态加载,直接使用LoadLibrary加载所需的动态库,然后指定所需的导出函数。一般情况下,两种方式都是可行的。如果我们没有头文件和.lib文件,只有dll,使用第二种方法是比较通用的作法。举例如下:
现有test.dll,有如下一些导出函数:
void func1(int a,int b);
int func2(int a,double b);
int func3(int* a,int* b);
//加载dll
HINSTANCE dllHinstance = LoadLibraryEx(dllFullName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
//dllFullName为包含路径的dll名称
//定义函数指针类型
typedef void(__stdcall *PROC1)(int,int);
typedef int(__stdcall *PROC2)(int,double);
typedef int(__stdcall *PROC3)(void*,int);//对于不能确定类型的指针用void*代替
//声明函数指针类型变量
PROC1 myProc1;
PROC2 myProc2;
PROC3 myProc3;
//获取函数指针存入对应变量
myProc1 = (PROC1) GetProcAddress(dllHinstance, "func1");
myProc2 = (PROC2) GetProcAddress(dllHinstance, "func2");
myProc3 = (PROC3) GetProcAddress(dllHinstance, "func3");
int a = 10;
int b = 5;
// 调用func1
(*myProc1)(a,b);
// 调用func2
int c = (*myProc2)(a,(double)b);
// 调用func3
c = (*myProc3)(&a,&b);
//调用完毕卸载dll
FreeLibrary(dllHinstance);
如果导出函数个数较多,或者导出函数被多次调用的情况下,可以构造头文件,通过宏的展开获取函数指针。如果dll被多次调用的话,伴随着宏多次展开的时间开销是一个不可忽略的因数。另外可借助专门工具对应生成.lib文件,采用隐式链接的方式加载。 如上所述,两种方法各有优劣,根据实际情况合理取舍。