.def 文件 vs2005生成dll
2010-12-02 11:19 bingcaihuang 阅读(1336) 评论(0) 收藏 举报entryname[=internalname] [@ordinal [NONAME]] [PRIVATE] [DATA]
1.entryname是要导出的函数名或变量名。这是必选项。如果导出的名称与 DLL 中的名称不同,则通过internalname指定 DLL 中导出的名称。例如,如果 DLL 导出函数 func1(),要将它用作 func2(),则应指定:2.@ordinal 允许指定是序号而不是函数名将进入 DLL 的导出表。这有助于最小化 DLL 的大小。.LIB 文件将包含序号与函数之间的映射,这使您得以像通常在使用 DLL 的项目中那样使用函数名。
EXPORTS func2=func1
此时用Dependency工具查看dll看到的函数名就是func2了,这个很好理解。
可选的 NONAME 关键字允许只按序号导出,并减小结果 DLL 中导出表的大小。但是,如果要在 DLL 上使用 GetProcAddress,则必须知道序号,因为名称将无效。
NONAME参数导出的dll和lib函数名测试如下:
用Dependency工具查看dll:

dumpbin -exports use_def_create_dll.lib命令查看lib导入库文件函数名如下:

可选的 PRIVATE 关键字禁止将 entryname 放到由 LINK 生成的导入库中。它对同样是由 LINK 生成的图像中的导出无效。


可以看出NONAME参数导出的dll中就只有序号了,什么含义也不知道,一般情况下就只有开发人员自己知道到底这个方法有什么用,同样,调用时用GetProcAddress调用也必须得知道序号,而真正的函数名写进了lib导入库中,所以如果隐式调用dll,把导入库加到附加依赖项中就可以不用管了,直接按照头文件调用;而PRIVATE参数就刚好相反,函数名写到dll里面去了,lib中就连个序号都没有,这时带着头文件,用GetProcAddress显式调用dll中的函数也是很方便的。
至于DATA参数,测试的时候发现用了跟没用并没有什么区别,暂时等待高手解决……
3.
有三种导出定义的方法,按照建议的使用顺序依次为:
1.代码中的 __declspec(dllexport) 关键字
2.def 文件中的 EXPORTS 语句
3LINK 命令的
/EXPORT规范
所有这三种方法可以用在同一个程序中。LINK 在生成包含导出的程序时还创建导入库,除非生成中使用了 .exp 文件。
如何从__declspec(dllexport)和def两种导出函数方法中作出选择,可以从以下的几个方面考虑:
如果需要使用导出顺序值(export ordinal value),那么应该使用DEF文件来导出函数。只在使用DEF文件导出函数才能指定导出函数的顺序值。使用顺序值的一个好处是当向DLL中添加新的函数时,只要新的导出函数的顺序值大于原有的导出函数,就没有必要重新链接使用隐含链接的应用程序。相反,如果使用__declspec(dllexport)来导出函数,如果想DLL中添加了新的函数,使用隐含链接的应用程序有可能需要重新编译和链接。
使用DEF文件从C++文件导出函数,应该在定义函数是使用extern "C"或者在DEF文件中指定导出函数的decorated name,否则,由于编译器所产生的decorated name是基于特定编译器的,链接到该DLL的应用程序也必须使用创建DLL的同一版本的Visual C++来编译和链接。
由于使用__declspec(dllexport)关键字导出函数不需要编写DEF文件,因此,如果编写的DLL只供自己使用,使用__declspec(dllexport)较为简单。
浙公网安备 33010602011771号