在利用DLL动态链接库的项目中,经常要用到dllexport和dllimport。我们这里把产生DLL的项目称作导出项目,把使用DLL的项目称作导入项目。
因为在导出项目和导入项目中,我们要分别使用dllexport和dllimport来定义我们的函数,比如:
在导出项目中,头文件要写成这个样子:
__declspec(dllexport) void showMessage(){
//...
}
而在导入项目中,头文件要写成这个样子:
__declspec(dllimport) void showMessage(){
//...
}
所以为了使导出项目和导入项目都使用同一个头文件,我们需要使用如下的方法来定义:
#ifdef SIMPLEDLL_EXPORT
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif
然后再在导出项目的预处理器中定义SIMPLEDLL_EXPORT;而在导入项目中则不需要任何定义。
另外:
__declspec(dllimport)如果不定义的话,在导入项目中也可以正常使用,但是有以下两个问题:
1. dllimport会对编译的汇编代码做优化,将间接调用变为直接调用。如下:
//如果不使用__declspec(dllimport)
call showMessage
showMessage: jmp dword ptr __imp_showMessage
//如果使用 __declspec(dllimport)
call dword ptr __imp_showMessage
注意showMessage是我们头文件中定义的符号,而DLL导出项目中定义的实际符号是__imp_showMessage。所以对于不加dllimport,编译器无法区分是普通函数还是导入函数。而加了的话,编译器知道这是一个导入函数,就能自动调用__imp_showMessage