2010-12-28 9 views
14

Ich habe versucht, eine einfache Testfunktion zu exportieren für eine DLL mit einer Anwendung zu arbeiten (FYI: mIRC), die die Aufrufkonvention als angibt:stdcall Namen extern c und Dllexport vs Moduldefinitionen Mangeln (msvC++)

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

Jetzt, um dies aus der Anwendung zu rufen, würde ich test_func verwenden, aber ich habe festgestellt, aufgrund mangelndem Namen ist es nicht so einfach, wie ich dachte.

Durch ähnliche Themen hier bin ich zu dem Verständnis gekommen, dass mit extern „C“ in Kombination mit __declspec (dllexport) ein equivelant ist (etwas) Verfahren zum Entfernen von Mangeln Definitionen Modul (def). Bei der Verwendung der extern/dllexport-Methode ist meine Funktion (als Beispiel) jedoch immer _test_func @ numbers, während die .def-Datei alle Fehler entfernt, die für die Verwendung mit der Anwendung erforderlich sind, für die ich exportieren musste.

Könnte jemand bitte erklären, warum das so ist? Ich bin nur neugierig auf die beiden Methoden. Vielen Dank!

Antwort

11

dllexport/import soll von selbst zurückgeladen werden, nicht eine alte C-Bibliothek mit GetProcAddress. Das Mangeln, das Sie gesehen haben, ist, was alle Microsoft-Compiler seit langem für __stdcall-Funktionen getan haben. Höchstwahrscheinlich erwartet Ihr Ziel entweder eine __cdecl-Funktion, nicht __stdcall, aber wenn nicht, müssen Sie eine .def-Datei verwenden, um den Namen speziell aufzuheben.

12

extern "C" hat nichts mit stdcall zu tun: es erklärt nur, dass C++ Name Mangling (auch typsichere Verknüpfung; Aufnahme von Typinformationen in Symbolname) deaktiviert ist. Sie müssen es unabhängig davon verwenden, ob Sie C-Aufrufkonvention oder Stdcall-Aufrufkonvention verwenden.

In Aufrufkonvention stdcall entfernt der Aufrufer die Parameter aus dem Stapel. Um dies zu gewährleisten, enthält der exportierte Name die Anzahl der Bytes, die der Angerufene vom Stapel entfernt.

Wenn die zu exportierende Anwendung erfordert, dass dem Namen kein @number Suffix hinzugefügt wird, bedeutet dies wahrscheinlich, dass C-Aufrufkonvention erwartet wird. Sie sollten also aufhören, die Funktion als __stdcall zu deklarieren. Wenn Sie es als declspec(dllexport) deklarieren, sollten Sie einen undecorated Name in der DLL abrufen.

In der DEF-Datei können Sie die Funktion aufrufen, was Sie wollen; es wird keine zusätzliche Überprüfung durchgeführt.

+15

Windows-API-Funktionen sind Stdcall, haben aber nicht @number und unter Windows ist es üblich, dies auf diese Weise zu tun. –