使用API函数GetProcAddress的注意事项

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

转自:点击打开链接

Windows API 函数 GetProcAddress 被广泛用于取得函数指针地址。 例如:

 

typedef BOOL (WINAPI *pfnGetProductInfo)(DWORD, DWORD, DWORD, DWORD, PDWORD);

 

pGPI = (pfnGetProductInfo) GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetProductInfo");

 

注意函数定义typedef 中的WINAPI, 它指定了函数的调用协议, 这部分是非常必要而且关键的,写代码的时候需要注意。

 

比如你要想取得标准C++运行库(msvcrt.dll) 中的strcpy函数,函数定义就应该是:

typedef char * (__cdecl *pfnStrRChr)(const char *string, int c);


pSRS = (pfnStrRChR)GetProcAddress(hMSVCRT, "strrchr");

 

函数调用协议指定了函数参数的传递方式以及栈管理方式。如果你这里不指定调用协议,编译器会用默认的调用协议。 结果可能和DLL 函数原先指定协议的不同,函数被调用时会直接导致程序崩溃

 

比较主流的函数调用方式有 _cdecl , _stdcall, _fastcall, _thiscall 。

_cdecl 是C语言默认的函数调用协议:所有参数从右到左依次入栈,栈中的参数由调用者清除。

_stdcall 是Pascal 语言的默认的函数调用协议,所有参数从右到左依次入栈,栈中的参数由被调用的函数在返回后清除。 Windows API 全部采用 _stdcall 方式, 上面例子中的WINAPI 其实就是 ___stdcall

#define WINAPI __stdcall
__fastcall 是前两个(x86机器)或者4个(x64机器)参数由寄存器传递,其余参数还是通过堆栈传递。 栈中的参数由被调用的函数在返回后清除。Borland Delphi, C++ Builder 默认使用这种调用方式。

_thiscall 和_stdcall 类似, 只是_thiscall 把类的this指针放在某个特定的寄存器中,比如Visual C++放在ECX中, Borland C++放在EAX中。

 

经比较,几种调用协议存在挺大差异,所以GetProcAddress 得到的函数需要指定正确的调用协议

关于GetProcAddress返回错误代码为127的解决方案 关于GetProcAddress返回错误代码为127的解决方案 关于GetProcAddress返回错误代码为127的解决方案 运行期间显示地去加载DLL库,当LoadLibrary可以返回当前DLL模块的句柄时,而GetProcAddress取得函数的地址为空时。通过GetLastError去获取错误代码为127,很有可能是动态链接库工程里面函数声明的没有加extern “C”。 解决方案 只针对自己写的dll项目提供解决方案, 如果是拿的第三方的动态链接库出这样的问题,不在此解决方案中。 通常写dll工 阅读详情

相关推荐

PB实现串口通信程序代码

本程序通过调用WINDOWS API函数,实现了类似MSCOMM控件的功能。使PB可以很方便地访问串口,免注册免配置环境,更方便、高效使用

【DLL】【一文搞懂】(四)GetProcAddress函数

一文搞懂动态库导入,GetProcAddress使用(动态库的显式链接)

此地无银 1万+

c++获取进程信息列表和进程所调用的dll列表

主要介绍了c++获取进程信息列表和进程所调用的dll列表,大家参考使用

GetprocAddress得到地址后该如何调用这个函数

http://topic.csdn.net/t/20040831/18/3327148.html //定义函数指针 VC++ GetProcAddress返回的是一个函数地址的指针。 声明:FARPROC WINAPI GetProcAddress(__in HMODULE hModule, __in LPCSTR LpProcName); 你应该知道你要的函数的类型是什么,可以用typedef的方法定义函数类型,然后定义一个这种类型的变量,你得到地址后,将地址的类型转换并存到那个变量中就行了。De

期待下集是个可爱梦儿 3009

[Windows编程] 使用API函数GetProcAddress注意事项

Windows API 函数 GetProcAddress 被广泛用于取得函数指针地址。 例如: typedef BOOL (WINAPI *pfnGetProductInfo)(DWORD, DWORD, DWORD, DWORD, PDWORD); pGPI = (pfnGetProductInfo) GetProcAddress(GetModuleHandleW(L"kern

IE浏览器开发 5533

[转载]使用API函数GetProcAddress注意事项

Windows API 函数 GetProcAddress 被广泛用于取得函数指针地址。 例如: typedef BOOL (WINAPI*pfnGetProductInfo)(DWORD, DWORD, DWORD, DWORD, PDWORD); pGPI = (pfnGetProductInfo) GetProcAddress(GetModuleHandleW(L...

angbagangzhe065140的博客 115

动态载入DLL所需要的三个函数详解(LOADLIBRARY,GETPROCADDRESS,FREELIBRARY)

(仅供参考) 动态载入DLL所需要的三个函数详解(LOADLIBRARY,GETPROCADDRESS,FREELIBRARY) 动态载入 DLL 动态载入方式是指在编译之前并不知道将会调用哪些 DLL 函数, 完全是在运行过程中根据需要决定应调用哪些函数。 方法是:用 LoadLibrary 函数加载动态链接库到内存,用 GetProcAddress函数动态获得 DLL 函数的入...

Charles_ke的博客 2010

解析Delphi中的LoadLibrary,GetProcAddress,FreeLibrary

 GetProcAddress(Hinstance,lpname)用来获取指定的动态连接库函数的地址 Hinstance为由LoadLibrary返回的模块句柄,lpname为文件名/函数名,返回值,成功返回动态连接库的地址,失败返回NULL, FreeLibrary(Hinstance),Hinstance为由LoadLibrary返回的模块句柄,功能是:释放动态连接库! 动态引

编程资料收集与共享交流 7717

详细介绍GetProcAddress()

作用从指定的 DLL 模块中检索导出函数的地址,支持通过函数名或序号访问。该函数是动态链接的核心实现,广泛应用于插件系统、内存注入、免杀技术等领域。函数原型​参数hModule:DLL 模块的句柄,可通过或获取。lpProcName:函数名(LPCWSTR)或序号(低 16 位为序号,高 16 位为 0)。返回值成功时返回函数地址FARPROC类型)。失败时返回NULL,可通过 GetLastError获取错误代码(如126表示模块未找到)。

felicity_one的博客 1578

LoadLibrary 和 GetProcAddress、FreeLibrary

<br />LoadLibrary("文件名")返回得到的模块句柄,可以加载一个动态连接库或exe文件。 <br />GetProcAddress(Hinstance,lpname)用来获取指定的动态连接库函数的地址 <br />Hinstance为由LoadLibrary返回的模块句柄,lpname为文件名/函数名,返回值,成功返回动态连接库的地址,失败返回NULL, <br />FreeLibrary(Hinstance),Hinstance为由LoadLibrary返回的模块句柄,功能是:释放动态连接

期待下集是个可爱梦儿 1000

win系统动态载入DLL所需要的三个函数详解(LoadLibrary,GetProcAddress,FreeLibrary)

动态载入 DLL动态载入方式是指在编译之前并不知道将会调用哪些 DLL 函数, 完全是在运行过程中根据需要决定应调用哪些函数。方法是:用 LoadLibrary 函数加载动态链接库到内存,用 GetProcAddress函数动态获得 DLL 函数的入口地址。当一个 DLL 文件用 LoadLibrary 显式加载后,在任何时刻均可以通过调用 FreeLibrary 函数显式地从内存中把它给卸载。动...

weixin_30813225的博客 1003
上一篇: C++重载箭头操作符
下一篇: Tab Control And List Control使用小记
ProgrammingRing
博客等级 码龄17年 76粉丝 31原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值