2009-09-23 12 views
25

J'essaie de créer une DLL qui exporte une fonction appelée "GetName". J'aimerais que d'autres codes puissent appeler cette fonction sans avoir à connaître le nom de la fonction mutilée.Comment arrêter la gestion des noms de la fonction exportée de ma DLL?

Mon fichier d'en-tête ressemble à ceci:

#ifdef __cplusplus 
#define EXPORT extern "C" __declspec (dllexport) 
#else 
#define EXPORT __declspec (dllexport) 
#endif 

EXPORT TCHAR * CALLBACK GetName(); 

Mon code ressemble à ceci:

#include <windows.h> 
#include "PluginOne.h" 

int WINAPI DllMain (HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved) 
{ 
    return TRUE ; 
} 

EXPORT TCHAR * CALLBACK GetName() 
{ 
    return TEXT("Test Name"); 
} 

Lorsque je construis, la DLL exporte toujours la fonction avec le nom: "_GetName @ 0" .

Qu'est-ce que je fais mal?

Répondre

21

correction Petit - pour la résolution du nom succès par clinet

extern "C" 

doit être aussi sur le côté à l'exportation à l'importation. "C" va réduire le nom de proc à: "_GetName"

extern

Plus sur vous pouvez forcer un nom avec l'aide de la section EXPORTATIONS dans le fichier .def

+0

Hey cool C'est exactement ce que je dois presque. Maintenant, que faire si je le veux dans l'autre sens? J'ai la fonction C, tout à fait bien être la fonction de membre C++ (vtable, convention d'appel tout fait), mais le compilateur chiffre son nom devrait être mutilé. – Pyjong

+0

Oui, C et C++ utilisent différentes règles de décoration de noms. Pour faire ce que vous demandez à propos de vous devez créer un wrapper qui appellera la fonction C du membre de la classe C++ – Dewfy

+0

Un fichier .DEF est le seul moyen de désactiver la gestion des noms. 'extern 'C" 'utilisera toujours la décoration de nom, mais pas aussi verbeux que le C++. – IInspectable

9

Ceci est normal pour une exportation DLL avec une convention __stdcall. Le @Nindicates the number of bytes that the function takes in its arguments - dans votre cas, zéro.

Notez que the MSDN page on Exporting from a DLL indique spécifiquement "utiliser la convention d'appel __stdcall" lors de l'utilisation "du mot-clé __declspec (dllexport) dans la définition de la fonction".

+1

Comme mentionné [ici] (http://stackoverflow.com/questions/2804893/c-dll-export-decorated-mangled-names), la seule façon de surmonter le mangling d'un '__stdcall' est d'utiliser: '#pragma comment (éditeur de liens,"/EXPORT: SomeFunction = _SomeFunction @@@ 23mangledstuff # @@@@ ")' – Pierre

+0

votre premier lien est brisé et le deuxième pointe vers un téléchargement –

4

la bonne réponse est la suivante:

extern "C" int MyFunc(int param); 

et

int MyFunc(int param); 

est deux déclarations qui utilise différentes dénomination interne, première - est en C -style, deuxième - dans le style C++. Nom interne requis pour les outils de construction pour déterminer quelle fonction d'arguments reçoit, quel type renvoie etc, puisque C++ est plus compliqué (oop, surchargé, fonctions virtuelles, etc.) - il utilise un nommage plus compliqué. La convention d'appel affecte également les noms C et C++.

ces deux styles de nommage sont appliqués lors de l'utilisation de __declspec (dllexport) de la même manière.

si vous voulez omettre le nom mangling de routine exporté, ajoutez un fichier de définition de module à votre projet, tapez (dans ce cas, vous ne devez declspec dllexport):

LIBRARY mylib 
EXPORTS 
    MyFunc 

cette omettra explicite décoration de nom (échantillons ci-dessous).

_MyFunc (c style, __cdecl) 
[email protected] (c style, __stdcall) 
[email protected]@[email protected] (c++ style, __cdecl) 
[email protected]@[email protected] (c++ style, __stdcall) 
0

Vous pouvez utiliser le commutateur de liens "-Wl, - kill-at" pour désactiver la gestion des noms.

Par exemple, dans le Code :: Blocks, dans les paramètres de l'éditeur de liens personnalisés, ajoutez: -Wl, - tuer à-