C++ DLL导出函数有两种方式(__declspec(dllexport)和.def文件)。c++加载DLL也有两种方式(静态链接和动态链接)。下面针对这4点分别进行讨论。
一.用__declspec(dllexport)导出函数:
例:
extern "C" __declspec(dllexport) int __stdcall add(int a, int b)
{return a + b;
}
导出的DLL函数如下:
Lib库函数如下:
可以用#pragma comment(linker,"/export:add=_add@8")来添加导出函数的重命名。
二.用.def导出函数。
dll导出函数为:
Lib库函数如下:
三.静态链接:
#pragma comment(lib,"xxx.lib")
声明如下:
extern "C" __declspec(dllimport) int __stdcall add(int a, int b);
链接的函数为:__imp__add@8.
声明如下:
extern "C" int __stdcall add(int a, int b);
链接的函数为:_add@8.
四.动态链接:
typedef int (__stdcall *ADDFUNC)(int a, int b);
HMODULE hDll = LoadLibrary(L"xxx.dll");
ADDFUNC add = (ADDFUNC)GetProcAddress(hDll, "_add@8");
加载的函数名必须和dll导出函数名一样,如果不一样是加载不到函数的。
如果函数声明的调用约定不同,则调用这个函数时会出错,如下:
typedef int ( *ADDFUNC)(int a, int b);
HMODULE hDll = LoadLibrary(L"xxx.dll");
ADDFUNC add = (ADDFUNC)GetProcAddress(hDll, "_add@8");
错误截图:
五.总结:
1.静态链接的时候不关心函数的导出函数名字,只有动态链接的时候才会关心函数的导出名字。
2.调用函数的时候一定要注意调用约定,不然会导致程序崩溃。