DLL的Export和Import

 
DLL export 是指将 DLL 中的函数和数据输出到其它程式中,以供其使用。 DLL import 是指使用 DLL 的程式引入 DLL 中的函数和数据。
 
DLL export
 
DLL 中包含有一个表,称为 export table (以下简称 ET ),其中包含了 DLL 中可以被外部程式使用的所有函数和数据的名字。只有记录在 ET 中的函数和数据才可以被外部程式所使用(如果没有 .DEF 文件的话),其它所有没有记录在 ET 中的函数和数据都被视为是 DLL 私有的。因此,要将 DLL 中的函数和数据 export 只有两个方法:
 
l          DLL 创建一个 .DEF 文件(模块定义文件),并在 build DLL 时使用这个 .DEF 文件。使用这种方法使你可以将函数按序号 export
 
l          DLL 中想要 export 的函数和数据定义前添加 _declspec dllexport )关键字(对于函数和变量定义,加在最前面;对于 class 定义,加在 class 关键字后),这样该函数和数据就会被添加到 ET 中。使用这种方法函数将按名字 export
 
WINDOWS 下,无论使用上述的哪一种方法,都必须要将 export 函数声明为 _stdcall
 
关于 C C++ 的兼容问题
 
如果要写 C C++ 兼容的 DLL ,因为在 C C++ 下使用了不同的名字修饰规则以及不同的调用约定,所以,如果 DLL 是用 C 编写和编译的,则在用于 C++ 模块时,函数的声明前应加上 extern “C” 关键字,以告诉 LINKER 使用 C 外部连接(即按照 C 名字修饰规则在外部模块中寻找函数);反之,如果 DLL 是用 C++ 编写和编译的,则在用于 C 模块时,函数的声明前要加上 extern “C++” 关键字。 VC++ 通过 _cplusplus 宏来标识 C++ 程式。如果是 C++ 程式, VC 编译器就会为你定义 _cplusplus 宏。所以在 DLL 中可以使用如下的技术来解决兼容问题:
 
#ifdef _cplusplus
 
extern “C” {
 
#endif
 
// 将所有的函数声明放在这里
 
#ifdef _cplusplus
 
}
 
#endif
 
.DEF 文件
 
         .DEF 文件是包含了 DLL 模块信息的文本文件。其语法结构如下:
 
         LIBRARY         DLL file name
 
         DESCRIPTION         “descriptions”
 
         EXPORTS
 
                  Function names        @nums
 
         LIBRARY 为关键字,后面紧跟关联的 DLL 文件名; DESCRIPTION 后为可选的描述字符串,除了增加可读性外没什么用处; EXPORTS 后是 export 函数的列表,首先是函数名,然后是 @ 符号,后紧跟一十进制数,为该函数的标号,范围从 1 DLL export 函数的总数。注意,这里的名字是经过名字修饰后的函数名字,如果是 DLL 是用 C++ 写的话,那么就很郁闷了。
 
         如果是扩展 DLL extension DLL ),并且通过 .DEF 文件 export ,那么必须在头文件中添加如下的语句:
            #undef AFX_DATA
               #define AFX_DATA AFX_EXT_DATA
               // 头文件中的其它内容
               #undef AFX_DATA
               #define AFX_DATA
 
这些语句确保一些 MFC 中内部使用的变量被 export 到外部程式中。例如:在 class 中通过 DECLARE_DYNAMIC 获得的 CRuntimeClass 变量。否则 DLL 将会无法正确地编译和连接,或外部程式无法正确连接到该 DLL
 
DLL import
 
         外部程式的一个源文件要使用 DLL 中的函数和数据,就像要使用外部模块中的函数和数据一样,必须首先给出函数和数据的声明;对于 class 则要给出类的定义。这就称为 import 。对于 VC 编译器, Import DLL 的函数和数据的语法与一般的声明类似,但要在前面加上 _declspec dllimport )关键字(对于函数和变量声明,加在最前面;对于 class 定义,加在 class 关键字后)。如果是函数,则该关键字是可选的,但使用该关键字有可能会导致编译器产生较高效的代码。但对于变量和 class ,则必须使用该关键字。
 
         通过使用以下的技术,可以编写在 .LIB 文件和外部程序源文件通用的头文件:
               #ifdef _EXPORTING
               #define CLASS_DECLSPEC    __declspec(dllexport)
           #else
                  #define CLASS_DECLSPEC    __declspec(dllimport)
               #endif
 
编译器提供的 _EXPORTING 宏可以用于标式该源文件来自 DLL 文件还是外部程式。 
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值