第一篇
参考原文链接:https://blog.csdn.net/HHT0506/article/details/116155724
背景
项目中需要对操纵手柄进行读取,在网上找了几篇博客,基本都是依赖winmm.lib,但其中一篇直接加载它的动态库,从里面把函数解析出来,虽然麻烦,但还是眼前一亮,竟然可以这么做!!!
由于不太熟悉typedef的这种操作,一开始没看懂,后来查了下,这是使用typedef定义的函数指针,并简单整理了这篇文章。
分析
以解析的第一个函数为例
QLibrary mylib("Winmm.dll");
typedef int (*MyPrototype) (HWND, UINT, UINT, BOOL);
MyPrototype qJoySetCapture = (MyPrototype)mylib.resolve("joySetCapture");
第一条语句是:定义一个库对象mylib,将目标dll加载进来;
第二条语句是:定义了一个函数指针类型,该类型定义的指针可指向返回值为int类型、函数参数为(HWND,UINT,UINT,BOOL)的函数;
第三条语句是:定义了一个函数指针qJoySetCapture。resolve函数中的joySetCapture是dll中的函数名,通过resolve进行解析,resolve返回的是该函数“joySetCapture”的地址,通过强制类型转化,再让qJoySetCapture指向该地址。
Example:
typedef int (*AvgFunction)(int, int);
AvgFunction avg = (AvgFunction) library->resolve("avg");
if (avg)
return avg(5, 8);
else
return -1;
The symbol must be exported as a C function from the library. This means that the function must be wrapped in an extern “C” if the library is compiled with a C++ compiler. On Windows you must also explicitly export the function from the DLL using the __declspec(dllexport) compiler directive, for example:
extern "C" __declspec(dllexport) int avg(int a, int b)
{
return (a + b) / 2;
}
总结
一般只有对某个dll非常熟悉,知道dll中包含哪些函数、函数参数个数及类型、返回值类型才使用这种方式加载并调用函数,否则,还是使用头文件+lib的方式调用函数。
另外,可以使用Dependency Walker查看dll中的函数