Pourquoi / quand est __declspec (dllimport) ne sont pas nécessaires?
-
11-10-2019 - |
Question
Dans un projet à l'aide d'un server.dll et un client.exe, je dllexport
ed un symbole de serveur de la dll du serveur, et pas dllimport
ed dans l'exe client.
Pourtant, les liens d'application, et commence, sans aucun problème. Est dllimport
pas nécessaire, alors ???
Détails:
J'ai cette dll 'serveur':
// 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;
et cet exécutable client:
#include <server.h>
int main() {
CServer s;
}
La ligne de commande du serveur:
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
ligne de commande client:
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
La solution
Il est pas nécessaire. Il est une optimisation, une indication pour le compilateur que la DLL va exporter le pointeur de fonction directement plutôt que d'une entrée dans l'IAT de la DLL. Le pointeur de la fonction exportée pour une fonction nommée foo () sera __imp_foo. Ce qui lui permet de générer un meilleur code, l'enregistrement d'une charge de pointeur de fonction de l'IAT et un saut indirect. Il est une optimisation du temps, pas d'espace.
blog a détails.