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
文件还是外部程式。