42

In a project using a server.dll and a client.exe, I have dllexported a server symbol from the server dll, and not dllimported it into the client exe.

Still, the application links, and starts, without any problem. Is dllimport not needed, then???

Details:

I have this 'server' 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;

and this client executable:

#include <server.h>
int main() {
   CServer s;
}

The server command line:

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

Client command line:

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
4

2 に答える 2

55

必須ではありません。これは最適化であり、DLLがDLLのIATの単なるエントリではなく、関数ポインタを直接エクスポートするというコンパイラへのヒントです。foo()という名前の関数のエクスポートされた関数ポインターは__imp_fooになります。これにより、より良いコードを生成でき、IATからの関数ポインターの負荷と間接ジャンプを節約できます。これは時間の最適化であり、スペースではありません。

このブログ投稿に詳細があります。

于 2010-12-20T14:29:39.543 に答える
0

私もこれについて疑問に思っていました。また、__declspec(dllimport) 命令を削除しましたが、別の dll (glib) の関数に依存する dll (gmodule) が問題なくコンパイルおよび実行 (特に Wireshark で) されたことに非常に驚きました。MSの引用は次のとおりです。

__declspec(dllimport) is ALWAYS required to access exported DLL data.

他のページでは指示が不要であると述べているため、なぜMSがこれを言っているのかわかりません。それにもかかわらず、私のライブラリは dllimport なしで実行されるだけでなく、以前は常に "__imp" シンボルに出くわしていましたが (または私に)、"__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?

プログラム全体の最適化が利用される場合。

于 2021-07-29T01:12:32.277 に答える