本文主要是介绍__declspec(dllexport) 与 .def,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
__declspec(dllexport) 与 .def
模块定义 (.def) 文件是包含一个或多个描述各种 DLL 属性的 Module 语句的文本文件。
1、二者的目的都是将公共符号导入到应用程序中或从 DLL 导出函数。
2、添加 __declspec(dllexport)是为了提供不使用.def文件从 .EXE 或 .DLL 导出函数的简单方法。
3、如果不使用 __declspec (dllimport) 或 __declspec(dllexport) 导出 DLL 函数,则 DLL 需要.def文件。
4、并不是任何时候选择添加 __declspec(dllexport)而放弃.def的方式都是好的。如果DLL是提供给VC++用户使用的,只需要把编译DLL时产生的.lib提供给用户,它可以很轻松地调用你的DLL。但是如果DLL是供VB、PB、Delphi用户使用的,那么会产生一个小麻烦。因为VC++对于__declspec(dllexport) 声明的函数会进行名称转换,如下面的函数:
__declspec(dllexport) int __stdcall IsWinNT()
会转换为IsWinNT@0,这样你在VB中必须这样声明:
Declare Function IsWinNT Lib "my.dll" Alias "IsWinNT@0" () As Long
@的后面的数由于参数类型不同而可能不同。这显然不太方便。所以如果要想避免这种转换,就要使用.def文件方式。
模块定义 (.def) 文件为 链接器 提供有关被链接程序的导出、属性及其他方面的信息。生成 DLL 时,.def 文件最有用。由于存在可代替模块定义语句使用的 链接器 选项,通常不需要 .def 文件。也可以将 __declspec(dllexport) 用作指定导出函数的手段。在 链接器 阶段可以使用 /DEF(指定模块定义文件)链接器选项调用 .def 文件。如果生成的 .exe 文件没有导出,使用 .def 文件将使输出文件较大并降低加载速度。
定义格式编辑
.def 文件中的第一条 LIBRARY 语句不是必须的,但LIBRARY 语句后面的 DLL 的名称必须正确,即与生成的动态链接库的名称必须匹配。此语句将 .def 文件标识为属于 DLL。 链接器将此名称放到 DLL 的 导入库中。
EXPORTS 语句列出名称,可能的话还会列出 DLL 导出函数的序号值。通过在函数名的后面加上 @ 符和一个数字,给函数分配序号值。当指定序号值时,序号值的范围必须是从 1 到 N,其中 N 是 DLL 导出函数的个数。
LIBRARY BTREE
EXPORTS
Insert @1
Delete @2
Member @3
Min @4
如果使用 MFC DLL 向导创建 MFC DLL,则向导将为您创建主干 .def 文件并将其自动添加到项目中。添加要导出到此文件的函数名。对于非 MFC DLL,必须亲自创建 .def 文件并将其添加到项目中。
如果导出 C++ 文件中的函数,必须将修饰名放到 .def 文件中,或者通过使用外部“C”定义具有标准 C 链接的导出函数。如果需要将修饰名放到 .def 文件中,则可以通过使用 DUMPBIN 工具或 /MAP 链接器选项来获取修饰名。请注意,编译器产生的修饰名是编译器特定的。如果将 Visual C++ 编译器产生的修饰名放到 .def 文件中,则链接到 DLL 的应用程序必须也是用相同版本的 Visual C++ 生成的,这样调用应用程序中的修饰名才能与 DLL 的 .def 文件中的导出名相匹配。
DEF文件还是很简单的,先举一个简单的例子(取决我的一个项目文件):
- ; AIDemo_CPP.def
- ; 该文件定义了DLL要导出的函数接口名
-
- LIBRARY "AIDemo_CPP"
-
- EXPORTS
- AI_Create @1
- AI_Destroy @2
- AI_Init @3
- AI_SetDepth @4
- AI_SetTimeLimit @5
- AI_PlaceChessman @6
- AI_Play @7
- AI_IsFull @8
- AI_IsWin @9
- AI_QuerySituation @10
- AI_QueryAuthorInfo @11
- AI_QueryAIInfo @12
-
- ; Ok, over
复制代码
DLL中用来定义给用户使用的API时,可以写一个.def文件
我知道的有三种方式 1. #ifndef __DELAYLOADLIB_H__ #define __DELAYLOADLIB_H__ #ifdef DELAYLOADLIB_EXPORTS # define DELAYLOADLIBAPI __declspec(dllexport) #else # define DELAYLOADLIBAPI __declspec(dllimport) #endif /* DELAYLOADLIB_EXPORTS */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ DELAYLOADLIBAPI int fnLib(); DELAYLOADLIBAPI int fnLib2(); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* __DELAYLOADLIB_H__ */ |
2. 写def用lib /def[:filename]命令处理 3. 在IDE的link选项指定def文件 def的目的是为了使用lib工具产生dll的引入库 供客户端编译时使用
这篇关于__declspec(dllexport) 与 .def的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!