注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

从C开始

 
 
 

日志

 
 

使用API函数GetProcAddress的注意事项 -- 调用协议  

2010-10-24 14:14:05|  分类: SDK编程 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

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

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

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

 

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

 

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

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


pfnStrRChr  pSRS = (pfnStrRChR)GetProcAddress(hMSVCRT, "strcpy");

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

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

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

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

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

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

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

  评论这张
 
阅读(608)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018