Question

J'écris une DLL C/C++ et je souhaite exporter certaines fonctions que j'ai effectuées avant d'utiliser un fichier .def comme celui-ci

LIBRARY "MyLib"
EXPORTS
  Foo
  Bar

avec le code défini comme ceci, par exemple :

int Foo(int a);
void Bar(int foo);

Cependant, que se passe-t-il si je souhaite déclarer une méthode surchargée de Foo() comme :

int Foo(int a, int b);

Comme le fichier def n'a que le nom de la fonction et non le prototype complet, je ne vois pas comment il gérerait les fonctions surchargées.Utilisez-vous simplement la seule entrée, puis spécifiez la version surchargée que vous souhaitez lors du passage du pointeur de fonction correctement prototypé vers LoadLibrary() ?

Modifier:Pour être clair, c'est sous Windows avec Visual Studio 2005

Modifier:J'ai marqué la méthode non-def (__declspec) comme réponse... Je sais que cela ne résout pas réellement le problème de l'utilisation des fichiers def comme je le voulais, mais il semble qu'il n'y ait probablement aucune solution (officielle) utilisant les fichiers def.Cependant, je laisserai la question ouverte, au cas où quelqu'un saurait quelque chose, nous n'avons pas de fonctions ni de fichiers def surchargés.

Était-ce utile?

La solution

Dans le code lui-même, marquez les fonctions que vous souhaitez exporter en utilisant __declspec(dllexport).Par exemple:

#define DllExport __declspec(dllexport)

int DllExport  Foo( int a ) {
  // implementation
}
int DllExport Foo( int a, int b ) {
  // implementation
}

Si vous procédez ainsi, vous n'avez pas besoin de répertorier les fonctions dans le fichier .def.

Alternativement, vous pourrez peut-être utiliser une valeur de paramètre par défaut, telle que :

int Foo( int a, int b = -1 )

Cela suppose qu'il existe une valeur pour b que vous pouvez utiliser pour indiquer qu'elle n'est pas utilisée.Si -1 est une valeur légale pour b, ou s'il n'y a pas ou ne devrait pas y avoir de valeur par défaut, cela ne fonctionnera pas.

Modifier (Adam Haile) :Corrigé pour utiliser __declspec car __dllspec n'était pas correct afin que je puisse marquer cela comme la réponse officielle... c'était assez proche.

Modifier (Graeme) :Oups, merci d'avoir corrigé ma faute de frappe !

Autres conseils

La surcharge de fonctions est une fonctionnalité C++ qui repose sur la modification des noms (les noms de fonctions énigmatiques dans les messages d'erreur de l'éditeur de liens).

En écrivant les noms mutilés dans le fichier def, je peux lier mon projet de test et l'exécuter :

LIBRARY "TestDLL"
EXPORTS
    ?Foo@@YAXH@Z
    ?Foo@@YAXHH@Z

semble fonctionner pour

void Foo( int x );
void Foo( int x, int y );

Copiez donc les noms des fonctions C++ du message d'erreur et écrivez-les dans votre fichier def.Cependant, la vraie question est :Pourquoi voulez-vous utiliser un fichier def et ne pas utiliser __declspec(dllexport) ?

Les noms mutilés ne sont pas portables, j'ai testé avec VC++ 2008.

J'ai eu un problème similaire, donc je voulais également poster à ce sujet.

  1. Utilisant habituellement

    extern "C" __declspec(dllexport) void Foo();
    

    exporter un nom de fonction, c'est bien.Ce sera généralement Exportez le nom sans mangeant sans avoir besoin d'un fichier .def.Il existe cependant quelques exceptions comme les fonctions __stdcall et les noms de fonctions surchargés.

  2. Si vous déclarez une fonction pour utiliser la convention __stdcall (comme cela est fait pour de nombreuses fonctions d'API)

    extern "C" __declspec(dllexport) void __stdcall Foo();
    

    Exportera un nom mutilé comme _foo @ 4.Dans ce cas, vous devrez peut-être explicitement cartographier le nom exporté vers un nom mulé interne.

UN.Comment exporter un nom intact.Dans un fichier .def, ajoutez

----
EXPORTS
    ; Explicit exports can go here

    Foo
-----

Cela tentera de trouver la « meilleure correspondance » pour une fonction interne Foo et de l’exporter.Dans le cas ci-dessus où il n'y a qu'un seul foo, cela créera la cartographie

Foo = _Foo@4

comme on peut le voir via dumpbin /EXPORTS

Si vous avez surchargé un nom de fonction, vous devrez peut-être explicitement dire quelle fonction vous souhaitez dans le fichier .def en spécifiant un nom mutilé à l'aide de la syntaxe EntryName [= internalName].par exemple.

----
EXPORTS
    ; Explicit exports can go here

    Foo=_Foo@4
-----

B.Une alternative aux fichiers .def est que vous pouvez exporter les noms "sur place" à l'aide d'un #pragma.

#pragma comment(linker, "/export:Foo=_Foo@4")

C.Une troisième alternative consiste à déclarer une seule version de Foo comme "C" externe à exporter sans modification.Voir ici pour plus de détails.

Il n'existe aucun moyen officiel de faire ce que vous voulez, car l'interface DLL est une API C.

Le compilateur lui-même utilise des noms mutilés comme solution de contournement. Vous devez donc utiliser la modification des noms lorsque vous ne souhaitez pas trop modifier votre code.

Il n'existe pas de moyen indépendant du langage ou de la version d'exporter une fonction surchargée, car la convention de modification peut changer à chaque version du compilateur.

C'est l'une des raisons pour lesquelles la plupart des fonctions WinXX portent des noms amusants comme *Ex ou *2.

La définition de Systax pour les EXPORTATIONS est :

entryname[=internalname] [@ordinal [NONAME]] [PRIVATE] [DATA]

nom de l'entrée est le nom de la fonction ou de la variable que vous souhaitez exporter.Ceci est nécessaire.Si le nom que vous exportez est différent du nom dans la DLL, spécifiez le nom de l'exportation dans la DLL avec internalname.

Par exemple, si votre DLL exporte une fonction func1() et que vous souhaitez qu'elle soit utilisée comme func2(), vous devez spécifier :

EXPORTS
func2=func1

Voyez simplement les noms mutilés (à l’aide de Dependency Walker) et spécifiez votre propre nom de fonctions.

Source: http://msdn.microsoft.com/en-us/library/hyx1zcd3(v=vs.71).aspx

Modifier:Cela fonctionne pour les DLL dynamiques, où nous devons utiliser GetProcAddress() pour récupérer explicitement une fonction dans la DLL.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top