在使用server.dll和client.exe的项目中,我dllexport
编辑了服务器dll中的服务器符号,并且不 dllimport
将其编入客户端exe。
仍然,应用程序链接并启动,没有任何问题。不需要dllimport
,那么???
详细信息:
我有这个'服务器'dll:
// server.h
#ifdef SERVER_EXPORTS
#define SERVER_API __declspec(dllexport)
#else
#define SERVER_API // =====> not using dllimport!
#endif
class SERVER_API CServer {
static long s;
public:
CServer();
};
// server.cpp
CServer::CServer(){}
long CServer::s;
和此客户端可执行文件:
#include <server.h>
int main() {
CServer s;
}
服务器命令行:
cl.exe /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_USRDLL"
/D "SERVER_EXPORTS" /D "_UNICODE" /D "UNICODE" /D "_WINDLL"
/Gm /EHsc /RTC1 /MDd /Yu"stdafx.h"
/Fp"Debug\server.pch" /Fo"Debug\\" /Fd"Debug\vc80.pdb"
/W3 /nologo /c /Wp64 /ZI /TP /errorReport:prompt
cl.exe /OUT:"U:\libs\Debug\server.dll" /INCREMENTAL:NO /NOLOGO /DLL
/MANIFEST /MANIFESTFILE:"Debug\server.dll.intermediate.manifest"
/DEBUG /PDB:"u:\libs\Debug\server.pdb"
/SUBSYSTEM:WINDOWS /MACHINE:X86 /ERRORREPORT:PROMPT
kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib
shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
客户端命令行:
cl.exe /Od /I "..\server"
/D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE"
/Gm /EHsc /RTC1 /MDd /Fo"Debug\\" /Fd"Debug\vc80.pdb" /W3 /c /Wp64 /ZI /TP
.\client.cpp
cl.exe /OUT:"U:\libs\Debug\Debug\client.exe" /INCREMENTAL
/LIBPATH:"U:\libs\Debug"
/MANIFEST /MANIFESTFILE:"Debug\client.exe.intermediate.manifest"
/DEBUG /PDB:"u:\libs\debug\debug\client.pdb"
/SUBSYSTEM:CONSOLE /MACHINE:X86
server.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
答案 0 :(得分:48)
不是必需的。这是一个优化,向编译器提示DLL将直接导出函数指针,而不仅仅是DLL的IAT中的一个条目。名为foo()的函数的导出函数指针将为__imp_foo。这允许它生成更好的代码,保存来自IAT的函数指针加载和间接跳转。这是时间优化,而不是空间。
此blog post包含详细信息。
答案 1 :(得分:0)
我也想知道这个。我还删除了 __declspec(dllimport) 指令,并且非常惊讶地看到依赖于另一个 dll (glib) 中的函数的 dll (gmodule) 编译和运行(特别是在wireshark 中)没有问题。这是 MS 的引用:
__declspec(dllimport) is ALWAYS required to access exported DLL data.
不知道为什么 MS 会这样说,因为在其他页面上他们声明该说明不是必需的。无论如何,我的库不仅在没有 dllimport 的情况下运行,而且我已经很久没有看到“__imp”符号了,而以前我一直在偶然发现它(或者它在我身上)。这是怎么回事?答案在这里:
That's why using __declspec(dllimport) is better: because the linker doesn't generate a thunk if it's not required. There's no thunk and no jmp instruction, so the code is smaller and faster. You can also get the same effect WITHOUT __declspec(dllimport) by using whole program optimization. For more information, see /GL (Whole Program Optimization).
现在说得通了。我在所有项目中都使用 /GL (+ /LTCG)。所以这就是主题问题的答案
when is __declspec( dllimport ) not needed?
当使用整个程序优化时。