【实战】如何在完全缺失头文件的情况下直接操作DLL
1. 引言:情况介绍
在常见的软件开发场景中,我们通常需要配套:
- .lib 文件(静态链接文件)
- .h 文件(头文件)
然而,实际工程中,有时只有 DLL 文件,没有配套头文件和静态库。 如果我们还想调用其中的函数,就需要自己动手来控制。
2. 技术基础:DLL 动态调用原理
一个 DLL 文件里包含了多个函数,其中通过 Export Table ( 导出表 ) 记录了函数名和地址。
进行调用的步骤:
-
使用
LoadLibraryA("xxx.dll")
,把 DLL 加载到内存 -
使用
GetProcAddress(hDll, "FuncName")
,根据函数名找到实际地址
【描述描述描述:DLL 动态调用流程】
[程序运行]
↓
[加载 DLL: LoadLibraryA]
↓
[获取函数地址: GetProcAddress]
↓
[将地址转成函数指针]
↓
[正常调用函数]
注意:GetProcAddress
返回的是通用指针(void*),需要将其转成正确的函数指针类型!
3. 操作示例:无 .lib/.h 情况下调用 DLL
3.1 加载 DLL
HMODULE hDll = LoadLibraryA("MyDriver.dll");
if (!hDll) {
std::cerr << "LoadLibrary failed!" << std::endl;
return -1;
}
3.2 解析函数
FARPROC funcAddress = GetProcAddress(hDll, "FunctionName");
if (!funcAddress) {
std::cerr << "GetProcAddress failed!" << std::endl;
return -1;
}
3.3 将地址转成函数指针
假设我们知道该函数类型:
typedef int (*MyFuncType)(int, int);
则可以:
MyFuncType myFunc = reinterpret_cast<MyFuncType>(funcAddress);
int result = myFunc(1, 2);
std::cout << "Result: " << result << std::endl;
4. 不知道函数类型怎么办?
- 后续实验:
- 先从无参数函数或简单基础类型开始测试
- 每次仅仅调用最基础操作,避免引起崩溃
5. 高级技巧:自定义的 DLL 加载器
可以封装成一个简单的类:
class DynamicDll {
public:
DynamicDll(const char* dllPath) {
hModule_ = LoadLibraryA(dllPath);
if (!hModule_) throw std::runtime_error("Failed to load DLL");
}
~DynamicDll() {
if (hModule_) FreeLibrary(hModule_);
}
template<typename T>
T loadFunction(const char* funcName) {
FARPROC addr = GetProcAddress(hModule_, funcName);
if (!addr) throw std::runtime_error("Function not found");
return reinterpret_cast<T>(addr);
}
private:
HMODULE hModule_;
};
使用示例:
DynamicDll dll("MyDriver.dll");
auto myFunc = dll.loadFunction<int(*)(int, int)>("FunctionName");
int result = myFunc(1, 2);
6. 常见问题总结
问题 | 可能原因 | 解决办法 |
---|---|---|
LoadLibrary |
DLL 路径错误,或 DLL 缺少依赖库 | 检查路径,用 Dependency Walker |
GetProcAddress |
函数名写错,大小写敏感 | 检查导出名单,确认正确名称 |
调用时崩溃 | 函数类型猜错,参数传递不对 | 根据文档确定正确类型 |
7. 结论
即使没有 .lib 和 .h,我们也可以使用:
LoadLibrary
把 DLL 加载到内存GetProcAddress
找到函数地址
阅读剩余
版权声明:
作者:傻狍子
链接:https://rowdeer.top/2025/04/28/%e3%80%90%e5%ae%9e%e6%88%98%e3%80%91%e5%a6%82%e4%bd%95%e5%9c%a8%e5%ae%8c%e5%85%a8%e7%bc%ba%e5%a4%b1%e5%a4%b4%e6%96%87%e4%bb%b6%e7%9a%84%e6%83%85%e5%86%b5%e4%b8%8b%e7%9b%b4%e6%8e%a5%e6%93%8d%e4%bd%9cdl/
文章版权归作者所有,未经允许请勿转载。
THE END