2010-12-28 9 views
14

Próbowałem eksportować prostą funkcję testową dla dll do pracy z aplikacją (FYI: mIRC), który określa konwencja wywołania jak:stdcall nazwa przekręcona użyciu extern C i dllexport vs definicji moduł (msvC++)

int __stdcall test_func(HWND mWnd, HWND aWnd, char *data, char *parms, BOOL show, BOOL nopause) 

Teraz, aby wywołać to z aplikacji, użyłbym test_func, ale zauważyłem, że z powodu manglingu nazwa nie jest tak prosta, jak myślałem.

Poprzez podobnych tematów tutaj doszedłem do zrozumienia, że ​​za pomocą extern „C” w połączeniu z __declspec (dllexport) stanowi equivelant (nieco) Sposób usuwania maglowania do modułu definicji (.def). Jednakże, używając metody extern/dllexport, moja funkcja (jako przykład) jest zawsze _test_func @ numbers, podczas gdy .def usunął wszystkie manipulacje wymagane do użycia z aplikacją, do której musiałem eksportować.

Czy ktoś mógłby wyjaśnić, dlaczego tak jest? Ciekawi mnie tylko te dwie metody. Dzięki!

Odpowiedz

11

Pliki dllexport/import są zaprojektowane do samodzielnego ładowania, a nie do starej biblioteki C za pomocą metody GetProcAddress. Widzieliśmy, co wszystkie kompilatory firmy Microsoft zrobiły przez długi czas dla funkcji __stdcall. Najprawdopodobniej twój cel oczekuje funkcji __cdecl, a nie __stdcall, ale jeśli nie, będziesz musiał użyć pliku .def, aby wyraźnie usunąć nazwę.

12

extern "C" nie ma nic wspólnego ze stdcall: deklaruje jedynie, że wymazanie nazw w C++ (zwane też bezpieczeństwem typu, włączenie informacji o typie w nazwie symbolu) jest wyłączone. Musisz go używać niezależnie od tego, czy używasz konwencji wywoływania C, czy konwencji wywoływania stdcall.

W konwencji wywołania stdcall, adresat usuwa parametry ze stosu. Aby było to bezpieczne, wyeksportowana nazwa zawiera liczbę bajtów, które usunie ze stosu.

Jeśli aplikacja, do której następuje eksportowanie, nie wymaga dodania sufiksu, prawdopodobnie oznacza, że ​​oczekuje konwencji wywołania C. Powinieneś przestać deklarować funkcję jako __stdcall. Kiedy zadeklarujesz to jako declspec(dllexport), powinieneś otrzymać niezdefiniowaną nazwę w bibliotece DLL.

W pliku DEF możesz wywołać funkcję, jak chcesz; nie są przeprowadzane dodatkowe kontrole.

+15

Funkcje windows api są stdcall, ale nie mają @ numer i na Windowsie jest to standardowa praktyka, aby zrobić to w ten sposób. –

Powiązane problemy