一、编写动态链接库
重要的是怎么导出动态链接库中的函数,首先要知道c/c++的默认的函数调用约定为__cdecl,Win32 API的调用约定是__stdcall(关于__函数的调用约定请自行百度)
1.若函数使用了Win32 API,则函数应使用__stdcall修饰
2.__stdcall会改变函数符号
3.因为c++在导出函数时会改变函数符号,应当用 extern "C"修饰
4.extern "C"和__stdcall不能同时修饰函数(有时候还是会改变函数符号)
5.用.def文件导出函数不会修改函数符号
总结:推荐使用.def导出函数(编译dll的时候就不需要后面两个头文件了),再手动编写两个mydlllib.h和mydll.h分别作为隐式链接和显示链接提供给使用者
拓展:使用__declspec(dllexport)导出函数的方法
在mydll.cpp添加
mydll.h不变
二、使用动态链接库
隐式调用:
1.包含mydlllib.h
2.将mydll.lib和mydll.dll复制到exe相同目录
显示调用:
1.包含mydll.h//不包含的话要自己typedef,不嫌麻烦的话也可以
2.将mydll.dll复制到exe相同目录
3.调用时:
mydll.cpp:
//dll的入口点
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
int myadd(int a,int b)
{
return a+b;
}
int __stdcall mysub(int a,int b)//这里只是为了说明使用__stdcall的情况
{
return a-b;
}
重要的是怎么导出动态链接库中的函数,首先要知道c/c++的默认的函数调用约定为__cdecl,Win32 API的调用约定是__stdcall(关于__函数的调用约定请自行百度)
1.若函数使用了Win32 API,则函数应使用__stdcall修饰
2.__stdcall会改变函数符号
3.因为c++在导出函数时会改变函数符号,应当用 extern "C"修饰
4.extern "C"和__stdcall不能同时修饰函数(有时候还是会改变函数符号)
5.用.def文件导出函数不会修改函数符号
总结:推荐使用.def导出函数(编译dll的时候就不需要后面两个头文件了),再手动编写两个mydlllib.h和mydll.h分别作为隐式链接和显示链接提供给使用者
mydlllib.h://隐式调用时需要包含的头文件
//这里仅仅是隐式调用dll时的头文件,如果要显示调用,应当再编写一个头文件供外部使用
#pragma once
#pragma comment(lib,"mydll.lib")//这里需要将mydll.lib放到exe文件相同目录
extern "C" __declspec(dllimport) int myadd(int,int); //声明一个可以导出的方法
extern "C" __declspec(dllimport) int __stdcall mysub(int,int); //tt
mydll.h://显式调用时需要包含的头文件
#pragma once
typedef int (* dll_myadd) (int,int);//这里加dll_只是为了在后面定义函数的时候可以取myadd这个变量名
typedef int (__stdcall* dll_mysub) (int,int);
拓展:使用__declspec(dllexport)导出函数的方法
在mydll.cpp添加
#define DLL_API extern "C" __declspec(dllexport)
//mydlllib.h写成:
#pragma once
#ifdef DLL_API
#else
#pragma comment(lib,"mydll.lib")//这里需要将mydll.lib放到exe文件相同目录
#define DLL_API extern "C" __declspec(dllimport)
#endif
DLL_API int myadd(int,int); //声明一个可以导出的方法
DLL_API int __stdcall mysub(int,int); //tt
mydll.h不变
二、使用动态链接库
隐式调用:
1.包含mydlllib.h
2.将mydll.lib和mydll.dll复制到exe相同目录
显示调用:
1.包含mydll.h//不包含的话要自己typedef,不嫌麻烦的话也可以
2.将mydll.dll复制到exe相同目录
3.调用时:
HINSTANCE hinstDLL;//获取dll
dll_myadd myadd;//定义函数名
dll_mysub mysub;//定义函数名
hinstDLL = LoadLibrary("sampleDLL.dll");
if (hinstDLL != NULL)
{
myadd = (dll_myadd) GetProcAddress(hinstDLL, "myadd");//获取函数地址
mysub = (dll_mysub) GetProcAddress(hinstDLL, "mysub");//获取函数地址
if (myadd != NULL)
myadd(1,2);
if (mysub != NULL)
mysub(1,2);
FreeLibrary(hinstDLL);
}