动态链接库
DllMain入口函数
- DllMain 函数不是用户必须提供的。
- 函数原型:BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD
fdwReason, LPVOID lpvReserved); - 参数一、当前DLL的加载基址,即模块句柄
- 参数二、当前的DLL在什么情况下被加载的。记得加break;
- define DLL_PROCESS_ATTACH 1 进程创建
- define DLL_THREAD_ATTACH 2 线程创建
- define DLL_THREAD_DETACH 3 线程结束
- define DLL_PROCESS_DETACH 0 进程结束
动态链接库的导出方式
- 在函数声明前使用 __declspec(dllexport)
- C++ 中使用这种方式导出的函数在被其它语言调用时会出现错误,因为C++ 为了区分重载函数使用的名称粉碎机制会对函数名进行一些特殊的处理,导致其它程序无法正确的获取函数名称。为了解决这个问题,一般在函数前面再加一个 extern "C",表示使用C方式的函数命名规则。
extern "C" __declspec(dllexport) void Func(int a, int b);
- C++ 中使用这种方式导出的函数在被其它语言调用时会出现错误,因为C++ 为了区分重载函数使用的名称粉碎机制会对函数名进行一些特殊的处理,导致其它程序无法正确的获取函数名称。为了解决这个问题,一般在函数前面再加一个 extern "C",表示使用C方式的函数命名规则。
- 使用模块定义文件进行声明(.def) 推荐使用
- 配置方式: 项目属性 > 连接器 > 输入 > 模块定义文件 > 定义的.def文件
- 以模块定义文件导出的函数默认没有名称粉碎机制
模块定义文件基础用法: 1. 指定导出表中显示的DLL名称:LIBRARY XXXX 2. 以序号方式导出函数:[FuncName] @[Number] 3. 只以序号导出函数: [FuncName] @[Number [NONAME]] VS2017中至少需要
动态链接库的调用方式
- 显式链接和隐式链接
- 显式链接:用于动态库(dll),调用 LoadLibrary 和GetProcAddress 动态获取函数
- 特点:不会影响程序的大小,便于升级,但是不易于跨平台
- 隐式链接:用于静态库(lib),使用 #pragma comment(lib, "xxx.lib") 链接静态库并包含头文件
- 特点:可能导致目标程序变大,但是增强了移植性
- 显式链接:用于动态库(dll),调用 LoadLibrary 和GetProcAddress 动态获取函数
评论区