这个是否对你帮助呢?
From Microsoft:
32 位版本的 Visual c + + 使用 _declspec(dllimport) 和 $ _declspec(dllexport) 来替换以前的 Visual c + + 的 16 位版本中使用该 __export 关键字。
您不需要使用您的代码的 _declspec(dllimport) 正确,编译,但这样做所以允许编译器以生成更好的代码。编译器将能够生成更好的代码,因为它肯定知道或不函数是否存在在 DLL 中,因此编译器可以生成跳过正常的间接寻址级别的代码会跨 DLL 边界的函数调用中出现。
使用正确的.def 文件导出部分,_declspec(dllexport) 不是必需的。_declspec(dllexport) 已添加到提供了一种从.exe 或.dll 导出函数,而无需使用.def 文件的简便方法。
本文的其余部分提供了相当低级别、 全面讨论这些问题。
Win32 可移植可执行文件格式旨在最大限度地减少必须能接触到修复的导入的页面数。若要执行此操作它将任何程序的所有导入地址放在一个称为导入地址表的位置。这就允许访问这些导入时修改只能有一个或两个页加载程序。
回到顶端
使用函数调用 _declspec(dllimport)
在下面的代码示例假定 func1 驻留在独立于.exe 文件包含 main () 函数的 DLL 中的函数。
_declspec(dllimport),不给出此代码:
void main(void) {
func1();
}
编译器生成类似下面的代码:
call func1
和链接器将为该调用到类似于下面这样:
call 0x4000000
; The address of 'func1'.
func1 存在另一个 DLL 中,如果链接器无法解析此直接因为它无法知道什么 func1 的地址。在 16 位环境中链接器将此代码地址添加到该加载程序在运行时用正确的地址修补该.exe 中的列表。在 32 位环境中链接器生成的它不会知道该地址的 thunk。在 thunk 如下所示:
0x40000000:
jmp DWORD PTR __imp_func1
__imp_func1 此处是 func1 的插槽中导入地址表.exe 文件的地址。链接器因此已知的所有地址。若要更新在加载时,一切就会正常工作的.exe 文件的导入地址表仅有加载程序。
因此,使用 _declspec(dllimport) 是更好的因为它是更好的如果链接器不生成一个 thunk,如果没有到。thunk 使代码更大 (RISC 系统上可以是几个说明) 并可能降低您的高速缓存的性能。如果您通知编译器函数是 DLL 中,它可以为您生成间接调用。
因此,现在此代码:
__declspec(dllimport) void func1(void);
void main(void) {
func1();
}
生成此指令:
call DWORD PTR __imp_func1
没有没有 thunk 和没有的 jmp 指令使代码更小、 更快。
另一方面,对于 DLL 内部的函数调用,您不希望不必使用间接调用。您已经知道函数的地址。时间和空间所需加载和存储前一个间接调用函数的地址,因此直接调用总是更快、 更小。您只想从外部调用的 DLL 函数时,请使用 __declspec(dllimport) DLL 本身。不要在一个 DLL 内部的函数上使用 __declspec(dllimport),生成该 DLL 时