为什么GetProcAddress获取不

名称修饰(decoration)的好处和坏处

dllexport属性告诉链接器:请将指定的函数标记为导出并为它生成一个导出项。这个导出项是经过修饰的,对于导出多个重载的函数来说,导出修饰后的名称是十分必要的。但是,这也意味着:你传入到GetProcAddress函数中的函数字符串也需要是修饰版本的。

从我们之前的几篇关于调用约定的文章中,我们知道,函数导出名称的修饰语法在各种硬件平台上是各不相同的,同时,随着调用约定的不同,导出的名称也会不同。举个例子,如果你从PowerPC平台上的一个DLL中导出一个函数,则你需要使用GetProcAddress(hinst,“..SomeFunction”)来获取这个这个函数指针。如果是平台上使用extern“C”__stdcall调用约定,则需要使用GetProcAddress(hinst,“_SomeFunction

8”)。如果使用的是__fastcall调用约定,则需要使用GetProcAddress(hinst,“

SomeFunction

8”)。

另外,C++里的名称修饰和编译器厂商相关。如果是MicrosoftC++编译器,则对于一个C++导出函数,需要使用GetProcAddress(hinst,“?SomeFunction

YGXHH

Z”),但是如果是BorlandC++编译器,则需要另外的函数字符串来表示。

所以,如果你开发了一个函数,你希望你的函数在各种不同的硬件平台,或者不同的语言,或者不同的C++编译器上都可以供客户调用,那么你必须导出它的未修饰版本。

当生成一个DLL时,编译器会同时生成一个对应的LIB文件,这个LIB文件会将修饰后的名称翻译成未经修饰的版本。所以,举个例子,如果客户代码需要获取函数_GetTickCount

0,则这个LIB文件会将它翻译为kernel32!GetTickCount。

课后练习题

既然dllexport属性将导出函数绑定到某个特殊的硬件平台,编译器或者语言(通过将函数导出为修饰版本),那为什么MSVCRT.DLL会使用这个属性呢?

最后

RaymondChen的《TheOldNewThing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。本文来自:《Whycan’tIGetProcAddressafunctionIdllexport’ed?》




转载请注明:http://www.aierlanlan.com/cyrz/3117.html

  • 上一篇文章:
  •   
  • 下一篇文章: