如何选择DLL中函数的导出方式

 本文讨论如何选择DLL函数的导出方式。
      作者:tyc611,2007-05-26
      要导出DLL中的函数,我们有两种方式:一是使用模块定义文件(.def文件);二是使用__declspec(dllexport)关键字。
 
      那么,应该选择哪种方式来导出DLL中的函数呢?要决定如何选择,你应该首先想清楚这个问题:谁将使用你的DLL?是你自己的应用使用的DLL,还是他人的应用使用的你的DLL作为第三方DLL?
 
      然后,你参考下面的.def和__declspec(dllexport)方式的优缺点及适用场合来决定如何选择。
 
      使用.def文件导出的优点
      (1)你能控制导出函数的名字。由于函数的不同调用约定所产生的函数名的Decorated Name是不同的(例如,__stdcall, __cdecl两种调用约定),所以为了得到简洁一致的导出函数名,就必须使用.def文件。
      (2)你能控制导出函数的序号。当你要构造一个供他人使用的第三方DLL时,你就需要确保每次更新的DLL中的函数名和序号都与以前的版本保持一致。当你添加额外的函数到DLL中时,通过赋予新函数较大的序号,从而新的DLL不会影响使用该DLL的应用(不管它是使用函数名还是使用序号调用函数的)。而要做到这些,就必须使用.def文件进行控制。例如,MFC中的DLL就是使用.def文件进行控制的。
      (3)还可控制导出函数的NONAME属性。通过指定导出函数的NONAME属性(EXPORTS语句:entryname[=internalname] [@ordinal[NONAME]] [DATA] [PRIVATE]),可以在DLL的导出表中不保存函数名,只保存序号,从而在有很多函数时节约很多空间。但同时也给DLL的使用者带来了困难,因为他们只能使用序号调用函数。所以,NONAME属性的使用并不多见(如果你想使你的DLL充满神秘,就用吧)。
 
      所以,使用.def的优点是很显然的,特别适用于第三方DLL的制作。
 
      使用__declspec(dllexport)的优点是简单、方便,但缺点是显而易见的,无法完成上面.def的工作。所以,它一般用于应用程序自己使用的DLL。这样,即使DLL的导出函数的Decorated Name有各种可能,应用在编译时都可以根据DLL的Import Library找到相应的函数,从而避免了上面.def文件所述的(1)和(2)的两个缺点。当DLL更新后,要使用新的DLL,也需要应用重新编译链接。
      如果文中有错误或遗漏之处,敬请指出,谢谢!

你可能感兴趣的:(工作,dll,mfc,import,library)