Pourquoi ne puis-je utiliser __declspec (dllexport) pour exporter DllGetClassObject () à partir d'une DLL COM?
-
27-09-2019 - |
Question
Je développe une dll COM et en essayant d'exporter la méthode DllGetClassObject () avec __ declspec (dllexport) .
Voici ma déclaration:
extern "C" HRESULT __declspec(dllexport) __stdcall DllGetClassObject(REFCLSID rclsid,
REFIID riid, void** ppv)
Mais je gardais obtenir cette erreur:
error C2375: 'DllGetClassObject' : redefinition; different linkage
J'essaie donc de vérifier toutes les occurrence des définitions de DllGetClassObject. Ainsi trouvé la suivante dans la section objbase.h .
STDAPI DllGetClassObject(__in REFCLSID rclsid, __in REFIID riid, __deref_out LPVOID FAR* ppv);
le STDAPI se révèle être comme ceci:
#define STDAPI EXTERN_C HRESULT STDAPICALLTYPE
dans d'autres termes, il est comme ceci:
#define STDAPI extern "C" HRESULT __stdcall
Selon MSDN :
Pour les fonctions d'exportation, la mot-clé __declspec (dllexport) doit apparaître à la gauche de la mot-clé appelant-convention, si mot-clé est spécifié.
Mais ma déclaration mentionnée avant tout n'a pas marché.
COM DLL Il en va de DEVONS exporter leurs méthodes avec def fichier?
Mise à jour 1
Je l'ai testé ma déclaration avec un nom de méthode différente, comme ci-dessous:
extern "C" HRESULT __declspec(dllexport) __stdcall f()
{
return S_OK;
}
Et cette méthode a été exportés avec succès. Ainsi, ces spécificateurs pourraient être utilisés ensemble. Il semble que le compilateur Visual C ++ prend STDAPI et extern "C" HRESULT __declspec (dllexport) __stdcall ne pas compatible.
La solution
Ce problème se produit je pense parce qu'une fonction __stdcall (pour 32 bits construit) est normalement décorée avec un préfixe et un underscore postfix @count
. Mais si la fonction est également marquée comme __declspec(dllexport)
décorations supplémentaires sont ajoutées (__imp
, je pense).
Vous pourriez être en mesure d'éviter d'utiliser un fichier .def avec le pragma suivant, si vous êtes prêt à vivre avec la pragma (je pense que je vais le fichier .def):
#pragma comment( linker, "/export:DllGetClassObject=_DllGetClassObject@12" )
Notez que pour une version x64, vous pourriez avoir à compiler conditionnellement le pragma, que je pense serait:
#pragma comment( linker, "/export:DllGetClassObject" )
Autres conseils
Il ne compile pas parce que la déclaration originale en objbase.h n'a pas l'attribut __declspec (dllexport). Vous ne pouvez pas ajouter dans la définition. Ne va pas aider de toute façon, la décoration de nom ne convient pas. Michael vous a montré ce qu'il faut faire à ce sujet.
Je vais sortir sur un membre et dire oui.
Même Visual Studio 2008 génère automatiquement le fichier .def pour ATL COM projets .dll.