C++中使用LoadLibrary加载DLL运行崩溃问题求助
问题分析与修复方案
你的程序崩溃的核心原因是代码里的赋值操作代替了相等判断,加上错误处理逻辑不完善,导致空指针调用。下面是具体的问题点和修复后的代码:
主要问题点
- 条件判断错误:在检查
GetProcAddress返回值时,你用了=(赋值)而不是==(相等比较)。比如if (p1 = NULL)会把p1直接设为NULL,这个表达式的值是NULL(逻辑假),所以错误提示不会执行,但p1已经是无效指针了,后续调用p1("1234")必然导致崩溃。 - 错误处理不严谨:
LoadLibrary失败时,LDLL是NULL,此时调用FreeLibrary(LDLL)是无效操作,会触发额外错误。- 获取函数地址失败后,没有终止流程,仍然继续执行后续的函数调用,必然访问空指针。
- 编译位数匹配:要确保你的CallDLL项目和
callbacktestDLL.dll的编译位数完全一致(都是32位或都是64位),否则即使LoadLibrary成功,函数调用也会出错。64位程序的导出函数名不会带有@参数字节数的后缀,这一点要注意。
修复后的完整代码
#include "stdafx.h" #include <iostream> #include <windows.h> typedef int (*P_to_Func1)(char*); // 指向StrToInt的指针类型 typedef char* (*P_to_Func2)(P_to_Func1, char*, int); // 指向NumCompare的指针类型 int main() { // 加载DLL HINSTANCE LDLL = LoadLibrary("callbacktestDLL.dll"); if (LDLL == NULL) { printf("DLL loading failed, error code: %d\n", GetLastError()); return 1; // 加载失败直接退出,无需调用FreeLibrary } // 获取StrToInt函数地址 P_to_Func1 p1 = (P_to_Func1)GetProcAddress(LDLL, "_StrToInt@4"); if (p1 == NULL) { printf("StrToInt loading failed, error code: %d\n", GetLastError()); FreeLibrary(LDLL); // 释放已加载的DLL return 1; } // 获取NumCompare函数地址 P_to_Func2 p2 = (P_to_Func2)GetProcAddress(LDLL, "_NumCompare@12"); if (p2 == NULL) { printf("NumCompare loading failed, error code: %d\n", GetLastError()); FreeLibrary(LDLL); // 释放已加载的DLL return 1; } // 调用StrToInt并输出结果 std::cout << "StrToInt(\"1234\") result: " << p1("1234") << std::endl; // 调用NumCompare并输出结果 char* compareResult = p2(p1, "1234", 20); if (compareResult != NULL) { std::cout << "NumCompare result: " << compareResult << std::endl; // 注意:如果compareResult是DLL内部分配的内存,需要确保DLL提供对应的释放函数,避免内存泄漏 } // 释放DLL FreeLibrary(LDLL); return 0; }
额外注意事项
- DLL路径:如果DLL不在程序运行目录下,需要指定完整路径,或者把DLL放到系统目录、程序目录,或者添加到PATH环境变量中。
- 内存管理:如果
NumCompare返回的char*是在DLL中用malloc分配的,那么必须在DLL中提供一个专门的内存释放导出函数,不能直接在调用程序中用free释放(因为CRT版本可能不兼容)。
内容的提问来源于stack exchange,提问作者YQ.Wang
相关产品推荐
相关产品推荐

