C++调用DLL问题:头文件仅提供函数指针typedef定义如何调用?
如何调用仅提供函数指针typedef的DLL函数
这事儿我太熟了,这种通过函数指针间接调用DLL函数的场景在老项目或者第三方闭源库中特别常见,我给你一步步说清楚操作流程,再附个完整示例:
核心步骤拆解
1. 加载目标DLL
首先你需要通过Windows API把DLL加载到当前进程的地址空间,用LoadLibrary或者它的宽字符版本LoadLibraryW都行。记得要检查加载是否成功,返回的HINSTANCE如果是NULL,说明加载失败(比如DLL路径不对、依赖缺失)。
2. 获取函数地址并转换为对应指针
用GetProcAddress函数从加载的DLL中取出目标函数的地址,然后把它强制转换成头文件里给的typedef函数指针类型。这里要注意:
- 第二个参数是文档里给的函数导出名(如果DLL用序号导出的话得用
MAKEINTRESOURCE(序号),但你说文档给了函数名,直接传字符串就行) - 必须严格匹配typedef里的调用约定(比如你这里的
__stdcall),不然会导致栈异常
3. 调用函数
转换完成后,你就可以像调用普通函数一样使用这个指针了。
4. 用完卸载DLL
调用FreeLibrary释放DLL资源,避免内存泄漏,尤其是在程序退出前或者不再需要DLL功能的时候。
完整代码示例
假设头文件里的typedef是:
typedef int (__stdcall *lpInitLib)();
那你的调用代码可以这么写:
#include <windows.h> #include <iostream> // 假设这是头文件里的typedef typedef int (__stdcall *lpInitLib)(); int main() { // 1. 加载DLL,这里替换成你的DLL实际路径 HINSTANCE hDll = LoadLibraryA("YourTarget.dll"); if (hDll == NULL) { std::cerr << "加载DLL失败,错误码:" << GetLastError() << std::endl; return 1; } // 2. 获取函数地址并转换指针 lpInitLib pInitLib = reinterpret_cast<lpInitLib>(GetProcAddress(hDll, "InitLib")); if (pInitLib == NULL) { std::cerr << "获取InitLib函数地址失败,错误码:" << GetLastError() << std::endl; FreeLibrary(hDll); // 加载成功但获取函数失败,记得先卸载DLL return 1; } // 3. 调用函数 int result = pInitLib(); std::cout << "InitLib调用结果:" << result << std::endl; // 4. 卸载DLL FreeLibrary(hDll); return 0; }
额外注意事项
- 如果DLL里的函数有参数,只要typedef里的参数列表和文档一致,调用时直接传参就行,和普通函数完全一样
- 调用约定一定要匹配!比如
__stdcall、__cdecl不能混,不然程序大概率崩溃 - 如果你的程序是64位的,要确保DLL也是64位的;32位程序对应32位DLL,否则加载会失败
内容的提问来源于stack exchange,提问作者Jardo




