2009-09-23 3 views
25

Ich versuche, eine DLL zu erstellen, die eine Funktion namens "GetName" exportiert. Ich möchte, dass anderer Code diese Funktion aufrufen kann, ohne den Namen der entstellten Funktion kennen zu müssen.Wie kann ich die Namensänderung der exportierten Funktion meiner DLL stoppen?

Meine Header-Datei sieht wie folgt aus:

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

EXPORT TCHAR * CALLBACK GetName(); 

Mein Code sieht wie folgt aus:

#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"); 
} 

Wenn ich bauen, die DLL exportiert nach wie vor die Funktion mit dem Namen: "_GetName @ 0" .

Was mache ich falsch?

Antwort

21

Kleine Korrektur - für den Erfolg der Lösung Namen von clinet

extern "C" 

wie beim Import wie auf Exportseite sein muss.

extern "C" reduziert den Namen von proc zu: "_GetName".

Mehr über Sie eine beliebigen Namen mit Hilfe von Abschnitt EXPORT in DEF-Datei erzwingen

+0

Hey kühl das ist genau das fast, was ich brauche. Was nun, wenn ich es andersherum möchte? Ich habe C-Funktion, völlig in Ordnung, C++ - Member-Funktion (vtable, Aufruf Konvention alles getan), aber der Compiler Zahlen sein Name sollte gemangelt werden. – Pyjong

+0

Ja, C und C++ verwenden unterschiedliche Regeln für die Namensdekoration. Um das zu tun, was Sie über Sie fragen, müssen Sie einen Wrapper erstellen, der die C-Funktion von C++ - Klassenmember aufruft. – Dewfy

+0

Eine .DEF-Datei ist die einzige Möglichkeit, die Namensverfälschung zu deaktivieren. 'extern" C "wird immer noch Namensdekoration verwenden, nur nicht so ausführlich wie C++. – IInspectable

9

Das ist normal für einen DLL-Export mit einer __stdcall Konvention. Die @Nindicates the number of bytes that the function takes in its arguments - in Ihrem Fall, Null.

Beachten Sie, dass the MSDN page on Exporting from a DLL ausdrücklich besagt, "die Aufrufkonvention __stdcall" zu verwenden, wenn "das Schlüsselwort __declspec (dllexport) in der Definition der Funktion" verwendet.

+1

Wie bereits [hier] (http://stackoverflow.com/questions/2804893/c-dll-export-decorated-migled-names) erwähnt wurde, ist die einzige Methode, um das Mangeln eines "__stdcall" zu beheben, die Verwendung von: '#pragma Kommentar (Linker,"/EXPORT: SomeFunction = _SomeFunction @@@ 23mangledstuff # @@@@ ")' – Pierre

+0

Ihre erste Verbindung ist kaputt und die zweite verweist auf einen Download –

4

die richtige Antwort ist folgende:

extern "C" int MyFunc(int param); 

und

int MyFunc(int param); 

zwei Erklärungen, die verschiedene interne Namensgebung verwendet, zuerst - in C -Stil, Sekunde - im C++ Stil.

interne Benennung erforderlich für Build-Tools zu bestimmen, welche Argumente Funktion erhält, welcher Typ usw. zurückgibt, da C++ komplizierter ist (oops, überladen, virtuelle Funktionen usw.) - es verwendet kompliziertere Namen. Die Aufrufkonvention wirkt sich auch auf C- und C++ -Namen aus.

Diese beiden Benennungsstile werden angewendet, wenn __declspec (dllexport) auf dieselbe Weise verwendet wird.

, wenn Sie Namen Mangeln der ausgeführten Routine verzichten wollen, eine Moduldefinitionsdatei zu Ihrem Projekt, geben Sie ihm hinzufügen (in diesem Fall, dass Sie nicht declspec Dllexport erforderlich):

LIBRARY mylib 
EXPORTS 
    MyFunc 

dieses auslassen explizites Namensdekoration (Beispiele unten).

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

Sie können den Link-Schalter "-Wl, - kill-at" verwenden, um die Namensänderung zu deaktivieren.

Zum Beispiel in Code :: Blocks, in den benutzerdefinierten Linker-Einstellungen hinzufügen: -Wl, - kill-at

Verwandte Themen