¿Por qué / cuándo no se necesita __declspec (dllimport)?

En un proyecto que usa un server.dll y un client.exe, tengo dllexport ed un símbolo de servidor del servidor dll, y no lo dllimport al exe del cliente.

Aún así, la aplicación vincula, y comienza, sin ningún problema. ¿No se necesita dllimport , entonces?

Detalles:

Tengo este dll ‘servidor’:

 // 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; 

y este ejecutable cliente:

 #include  int main() { CServer s; } 

La línea de comando del servidor:

 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 

Línea de comando del cliente:

 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 

No es requerido Es una optimización, una sugerencia para el comstackdor de que el archivo DLL va a exportar el puntero a la función directamente en lugar de solo una entrada en el IAT de la DLL. El puntero de función exportado para una función llamada foo () será __imp_foo. Lo que le permite generar un mejor código, guardando una carga del puntero de función del IAT y un salto indirecto. Es una optimización de tiempo, no de espacio.

Esta publicación de blog tiene los detalles.