2009-09-23 14 views
25

Próbuję utworzyć bibliotekę DLL, która eksportuje funkcję o nazwie "GetName". Chciałbym, aby inny kod mógł zadzwonić do tej funkcji bez znajomości nazwy funkcji.Jak zatrzymać wywoływanie nazw funkcji eksportowanej przez bibliotekę DLL?

Mój nagłówek pliku wygląda następująco:

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

EXPORT TCHAR * CALLBACK GetName(); 

Mój kod wygląda następująco:

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

Kiedy budować, DLL nadal eksportuje funkcję o nazwie: "_GetName @ 0" .

Co robię źle?

Odpowiedz

21

Mała korekta - na sukces rozwiązywania nazwy przez clinet

extern "C" 

musi być po stronie eksportu, jak na imporcie.

extern "C" zredukuje nazwę procu do: "_GetName".

Ponad to można wymusić dowolną nazwę z pomocą eksportu sekcji w pliku .def

+0

Hej fajne to jest dokładnie to prawie co muszę. A co jeśli chcę tego na odwrót? Mam funkcję C, całkowicie w porządku, aby być C++ członkiem funkcji (vtable, wywołanie konwencji wszystko zrobione), ale kompilator twierdzi, że jego nazwa powinna zostać zmanipulowana. – Pyjong

+0

Tak, C i C++ używają różnych reguł dekorowania nazw. Aby zrobić to, o co pytasz, potrzebujesz utworzyć wrapper, który wywoła funkcję C z klasy C++. – Dewfy

+0

Plik .DEF to jedyny sposób na wyłączenie mangowania nazw. 'extern" C "' nadal będzie używać dekorowania nazw, po prostu nie tak gadatliwego jak to wymaga C++. – IInspectable

9

Jest to normalne dla eksportu DLL z __stdcall konwencji. @Nindicates the number of bytes that the function takes in its arguments - w twoim przypadku zero.

Zwróć uwagę, że the MSDN page on Exporting from a DLL mówi konkretnie, aby "używać konwencji wywołania __stdcall" podczas używania słowa kluczowego __declspec (dllexport) w definicji funkcji ".

+1

Jak wspomniano [tutaj] (http://stackoverflow.com/questions/2804893/c-dll-export-decorated-mangled-names), jedyny sposób na pokonanie zniekształcenia '__stdcall' jest użycie: '#pragma comment (linker,"/EXPORT: SomeFunction = _SomeFunction @@@ 23mangledstuff # @@@@ ")' – Pierre

+0

twoje pierwsze łącze jest zepsute, a drugie wskazuje na zły pomysł: –

4

dobrym rozwiązaniem jest następujący:

extern "C" int MyFunc(int param); 

i

int MyFunc(int param); 

jest dwa deklaracji, które wykorzystuje różne nazewnictwo wewnętrzne, pierwsze - w C styl, drugi - w stylu C++.

Nazywanie wewnętrzne wymagane dla narzędzi kompilacji w celu określenia, która funkcja argumentów otrzymuje, jakiego typu zwraca itp., Ponieważ C++ jest bardziej skomplikowana (funkcje, przeciążenia, funkcje wirtualne itp.) - używa bardziej skomplikowanego nazewnictwa. Wywołanie konwencji wpływa również na nazwy w językach c i C++.

oba te style nazewnictwa są stosowane podczas używania __declspec (dllexport) w ten sam sposób.

jeśli chcesz pominąć nazwę maglowania eksportowanego rutyny, dodać plik definicji modułu do projektu, typ w nim (w tym przypadku nie wymaga się declspec dllexport):

LIBRARY mylib 
EXPORTS 
    MyFunc 

zostanie pominięty jawne dekoracje nazwy (próbki poniżej).

0

Możesz użyć przełącznika link "-Wl, - kill-at", aby wyłączyć wymazywanie nazw.

Na przykład w Code :: Blocks, łączącymi w ustawieniach niestandardowych, dodać: -Wl, - kill-at

Powiązane problemy