__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文件还是很简单的,先举一个简单的例子(取决我的一个项目文件):
  1. ; AIDemo_CPP.def
  2. ; 该文件定义了DLL要导出的函数接口名

  3. LIBRARY        "AIDemo_CPP"

  4. EXPORTS
  5.     AI_Create             @1
  6.     AI_Destroy            @2
  7.     AI_Init               @3
  8.     AI_SetDepth           @4
  9.     AI_SetTimeLimit       @5
  10.     AI_PlaceChessman      @6
  11.     AI_Play               @7
  12.     AI_IsFull             @8
  13.     AI_IsWin              @9
  14.     AI_QuerySituation     @10
  15.     AI_QueryAuthorInfo    @11
  16.     AI_QueryAIInfo        @12

  17. ; 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的引入库 供客户端编译时使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值