目录
C++共享函数库有两种方式,动态库和静态库,动态链接库提供了一种方法,使进程可以调用不属于其可执行代码的函数。函数的可执行代码位于一个 DLL 文件中,该 DLL 包含一个或多个已被编译、链接并与使用它们的进程分开存储的函数。
使用vs创建dll动态链接库项目,vs自动生成代码解析如下图。
当我们需要给使用dll库的开发者提供可调用函数时,我们需要将自己编写的功能函数进行导出,在vs下导出的方式有很多,最常用的方法是在需要导出的函数前加 关键字 _declspec(dllexport) ,为了兼容性一般 以 extern "C" 的方式导出,示例如下。
- // dllmain.cpp : 定义 DLL 应用程序的入口点。
- #include "pch.h"
-
- //dll入口函数
- BOOL APIENTRY DllMain( HMODULE hModule,//指向dll本身的实例句柄
- DWORD ul_reason_for_call,//dll被调用的原因
- LPVOID lpReserved//保留参数
- )
- {
- switch (ul_reason_for_call)
- {
- case DLL_PROCESS_ATTACH: //dll第一次被调用时,即当dll刚被注入时就会启动
- case DLL_THREAD_ATTACH://进程创建一线程时
- case DLL_THREAD_DETACH://线程调用了ExitThread来结束线程时
- case DLL_PROCESS_DETACH://dll被从进程的地址空间解除映射时
- break;
- }
- return TRUE;
- }
-
- extern "C" _declspec(dllexport) void showWindow()
- {
- MessageBoxA(NULL, "hello,I am dll", "dll", MB_OK);
- }
-
首先使用 LoadLibraryA 加载dll模块,函数只有一个参数:模块的名称。这可以是库模块(.dll文件)或可执行模块(.exe文件)。然后调用GetProcAddress(),获取模块中函数的地址,一般使用函数指针来接受其返回值。
GetProcAddress函数原型
FARPROC GetProcAddress(
[in] HMODULE hModule,
[in] LPCSTR lpProcName
);
[in] hModule
包含函数或变量的 DLL 模块的句柄。LoadLibrary、LoadLibraryEx、LoadPackagedLibrary 或 GetModuleHandle 函数返回此句柄。
[in] lpProcName
函数或变量名称,或函数的序号值。如果此参数是序数值,则必须在低阶字中;高阶字必须为零。
示例代码
- #include<windows.h>
-
- typedef void (*Func)(void);
-
- int main()
- {
- HMODULE mod=LoadLibraryA("Dll1.dll");
- Func fp = (Func)GetProcAddress(mod, "showWindow");
-
- fp();
- return 0;
- }
运行截图