Überladene Funktionen in der C ++ - DLL-Def-Datei

9

Ich schreibe eine C / C ++ - DLL und möchte bestimmte Funktionen exportieren, die ich vor der Verwendung einer .def-Datei wie dieser gemacht habe

%Vor%

mit dem so definierten Code, zum Beispiel:

%Vor%

Was aber, wenn ich eine überladene Methode von Foo () wie:

deklarieren möchte %Vor%

Da die def-Datei nur den Funktionsnamen und nicht den vollständigen Prototyp hat, kann ich nicht sehen, wie sie mit den überladenen Funktionen umgehen würde. Verwenden Sie nur den einen Eintrag und geben Sie dann an, welche überladene Version bei der Übergabe des ordnungsgemäß prototypierten Funktionszeigers an LoadLibrary ()?

verwendet werden soll

Bearbeiten: Um dies zu verdeutlichen, ist dies unter Windows mit Visual Studio 2005

Bearbeiten: Markierte die Nicht-Def (__declspec) -Methode als Antwort ... Ich weiß, dass dies das Problem mit Def-Dateien nicht löst, wie ich wollte, aber es scheint, dass es wahrscheinlich keine (offizielle) Lösung gibt def Dateien. Wird die Frage offen lassen, aber falls jemand etwas weiß, haben wir keine überladenen Funktionen und Def-Dateien.

    
Adam Haile 25.08.2008, 14:22
quelle

6 Antworten

9

Markieren Sie im Code selbst die zu exportierenden Funktionen mit __declspec (dllexport). Zum Beispiel:

%Vor%

Wenn Sie dies tun, müssen Sie die Funktionen in der .def-Datei nicht auflisten.

Alternativ können Sie einen Standardwert für den Parameter verwenden, wie zum Beispiel:

%Vor%

Dies setzt voraus, dass ein Wert für b vorhanden ist, mit dem Sie angeben können, dass es nicht verwendet wird. Wenn -1 ein zulässiger Wert für b ist, oder wenn es keinen Standard gibt oder nicht, funktioniert das nicht.

Bearbeiten (Adam Haile): Korrigiert, __declspec als __dllspec zu verwenden, war nicht korrekt, also könnte ich das als offizielle Antwort markieren ... es war nah genug.

Edit (Graeme): Ups - danke für die Korrektur meines Tippfehlers!

    
Graeme Perrow 25.08.2008, 14:32
quelle
11

Das Überladen von Funktionen ist eine C ++ - Funktion, die auf Namensfehlern beruht (die kryptischen Funktionsnamen in den Linker-Fehlermeldungen).

Indem ich die entstellten Namen in die def-Datei schreibe, kann ich mein Testprojekt verlinken und ausführen lassen:

%Vor%

scheint für

zu funktionieren %Vor%

Kopieren Sie also die C ++ - Funktionsnamen aus der Fehlermeldung und schreiben Sie sie in Ihre def-Datei. Die eigentliche Frage ist jedoch: Warum wollen Sie eine Def-Datei verwenden und nicht mit __declspec (dllexport) gehen?

Die entstellten Namen sind nicht portierbar, ich habe mit VC ++ 2008 getestet.

    
Timbo 25.08.2008 14:42
quelle
8

Ich hatte ein ähnliches Problem, also wollte ich auch hier posten.

  1. Normalerweise mit

    %Vor%

    zum Exportieren eines Funktionsnamens ist in Ordnung. Es wird normalerweise den Namen exportieren ohne ein Bedürfnis nach einem .def-Datei. Es gibt jedoch einige Ausnahmen wie __stdcall-Funktionen und überladene Funktionsnamen.

  2. Wenn Sie eine Funktion deklarieren, die Sie verwenden möchten __stdcall Konvention (wie es für viele API-Funktionen getan wird) dann

    %Vor%

    exportiert einen entstellten Namen wie _Foo @ 4. In diesem Fall müssen Sie den exportierten Namen möglicherweise explizit zuordnen zu einem internen Mangled Name.

A. So exportieren Sie einen nicht verwalteten Namen Fügen Sie in einer DEF-Datei

hinzu %Vor%

Dies wird versuchen, eine "beste Übereinstimmung" für eine interne Funktion Foo zu finden und sie zu exportieren. In dem Fall oben, wo es nur gibt ein foo das wird das Mapping

erstellen

Foo = _Foo @ 4

wie man es via dumpbin / EXPORTS sehen kann

Wenn Sie einen Funktionsnamen überladen haben, müssen Sie möglicherweise explizit angeben, welche Funktion in der .def-Datei verwendet werden soll durch Angabe eines Mangled-Namens mit der Syntax von [[]]. z.B.

%Vor%

B. Eine Alternative zu .def-Dateien besteht darin, dass Sie Namen mit einem #pragma "an Ort und Stelle" exportieren können.

%Vor%

C. Eine dritte Alternative besteht darin, nur eine Version von Foo als extern "C" zu deklarieren, die unmigriert exportiert werden kann. Einzelheiten hierzu finden Sie hier .

    
04.12.2008 21:03
quelle
3

Es gibt keine offizielle Möglichkeit, das zu tun, was Sie wollen, weil die DLL-Schnittstelle ein CAPI ist.

Der Compiler verwendet selbst gemangelte Namen als Workaround, daher sollten Sie name mangling verwenden, wenn Sie nicht zu viel in Ihrem Code ändern möchten.

    
Christopher 27.08.2008 11:11
quelle
2

Es gibt keine sprach- oder versionsunabhängige Möglichkeit, eine überladene Funktion zu exportieren, da sich die Mangling-Konvention mit jeder Version des Compilers ändern kann.

Dies ist ein Grund, warum die meisten WinXX-Funktionen lustige Namen wie * Ex oder * 2 haben.

    
Mat Noguchi 25.08.2008 15:54
quelle
2

Die Definition von Systax for EXPORTS lautet:

%Vor%

Eintragsname ist der Name der Funktion oder der Variablen, die Sie exportieren möchten. Dies ist erforderlich. Wenn der Name, den Sie exportieren, sich von dem Namen in der DLL unterscheidet, geben Sie den Namen des Exports in der DLL mit internalname an.

Wenn Ihre DLL beispielsweise eine Funktion func1 () exportiert und Sie sie als func2 () verwenden möchten, geben Sie Folgendes an:

%Vor%

Sehen Sie sich einfach die entstellten Namen an (mit Dependency Walker) und geben Sie Ihren eigenen Funktionsnamen an.

Quelle: Ссылка

Bearbeiten: Dies funktioniert für dynamische DLLs, wo wir GetProcAddress () verwenden müssen, um explizit eine Funktion in DLL abzurufen.

    
null 21.03.2013 06:15
quelle

Tags und Links