Подтвердить что ты не робот

Почему/когда __declspec (dllimport) не требуется?

В проекте, использующем server.dll и client.exe, у меня есть dllexport ed символ сервера из 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
4b9b3361

Ответ 1

Это не требуется. Это оптимизация, подсказка для компилятора, что DLL собирается экспортировать указатель на функцию напрямую, а не только запись в IAT библиотеки DLL. Указателем экспортируемой функции для функции с именем foo() будет __imp_foo. Это позволяет ему генерировать более эффективный код, сохраняя нагрузку указателя на функцию из IAT и косвенный скачок. Это оптимизация времени, а не пробел.

В этом сообщении в блоге есть подробности.