[DLL-Bau] Export von Funktionen

mueslirocker

Mitglied
Hi!

Ich arbeite (wie immer :) ) mit cygwin und nutze entsprechend den GNU Compiler gcc bzw g++.

Ich habe viel gelesen´und der Bau einer DLL ist ja nicht schwer, aber mir sind zwei Dinge nicht klar geworden.

Vorweg wie ich kompiliere und linke:
gcc -c dllname.cpp
g++ -shared -o dllname.dll dllname.o

Wenn ich mir die DLL nun anschaue und nach meinen Funktionsnamen suche, finde ich sie zwar, aber es wurden Buchstaben hinzugefügt.
Die Funktion "test" heißt z.B. "_Z11testi".
Wenn ich das richtig sehe, ist das Präfix immer _Z<eineZahl> und das Postfix entweder "i" oder "PKcmPcm"... kann aber auch sein, dass es nur bei den Beispielen, die ich mir angeschaut habe, so ist.

Ich habe gelesen, dass man ein DEF-File bauen kann, in dem dann "EXPORTS test@1" stehen soll.
Ich weiß aber nicht, wie ich dieses DEF-File beim Linken einbringen soll.
Ferner habe ich gelesen, dass man aus einer DLL ein DEF-File generieren kann. Und aus der DLL und der DEF eine andere Bibliothek (.a) bauen kann.
(echo EXPORTS > foo.def
nm foo.dll | grep ' T _' | sed 's/.* T _//' >> foo.def
dlltool --def foo.def --dllname foo.dll --output-lib foo.a)

Ich habe mir einfach mal ein DEF-File bauen lassen und reingeschaut und dabei ist mir aufgefallen, dass wirklich alle Funktionen, die in meinem Programm (oder dessen Header) auftauchen, exportiert werden... aber nicht alle bekommen ein "@<eineZahl>".
Ist diese Zahl hinter dem @ der Einstiegpunkt?

Das bringt mich zu meiner zweiten Frage.
Wie kann ich bestimmen, welche Funktionen exportiert werden, und welche nicht?

Achso, damit nur bestimmte Funktionen exporiert werden, habe ich diese mit "__declspec(dllexport)" versehen.
Scheint dem Linker aber egal zu sein.
Ich habe das Gefühl, als dürfte ich nicht mit dem Parameter -shared arbeiten..

Es ist auch so, dass ich mit einem anderen C-Programm, das beim Linken die DLL einbindet, und einen entsprechenden Header hat ("__declspec(dllimport)"), die Funktionen mit ihrem normalen Namen benutzen kann, aber ich möchte die DLL nicht nur in C-Programmen einbauen und die DLL auch weiter geben und dafür möchte ich schon die selbstgebaute DEF-Datei mit den sprechenden Namen benutzen und auch die Einstiegspunkte (also die Zahlen hinter dem @.. sind das die Einstiegspunkte?) bestimmen.

Kann mir jemand helfen?
 
Ich habe mich noch ein wenig hiermit beschäftigt.

Nur bestimmte Methoden/Funktionen kann ich mit dem Befehl dllwrap in die DLL exportieren.
Diese will eine DEF-Datei.
Füttere ich dllwrap aber mit einer DEF-Datei, die die normalen Namen beinhaltet, sind das undefinierte Referenzen. :(


Diese komischen Namen haben alle Funktionen und nicht nur die, die ich als exportiert marktiert habe - und das schon in der Objekt-Datei.
Als Präfix scheint wirklich immer "_Z<eineZahl>" zu kommen und das Postfix scheint von den Parametern abzuhängen.

Ich habe im Netz viele Beispiele gefunden, wie man ein DEF-File mit den normalen Namen schreibt und dann mit VS daraus eine DLL-Datei erzeugt.
Aber ich finde nirgends die Kommandos zum Kompilieren und Linken.
Scheinbar muss ich ja beim Kompilieren schon ansetzen, wenn ich die Methoden unter ihren normalen Namen exportieren möchte.
Da komme ich aber nicht weiter. :(

Weiß niemand etwas über den DLL Bau unter Linux (bzw unter Windows mit cygwin/mingw)?

/edit
Ich bin beim dlltool auf die Option --add-stdcall-alias gestoßen.
Hab danach mal in die erzeugt DEF-Datei geschaut und solche Zeilen gefunden.
_Z11<fkt_name>i = _Z11<fkt_name>i@4 @ 5 ;
Kann man vor das = beliebiges schreiben?
Und nützt das was?
Ich habe die DEF-Datei dann gändert.
<fkt_name> = _Z11<fkt_name>i@4 @ 5 ;
Die DLL konnte ich so erzeugen, aber die Funktion konnte immernoch nicht richtig benutzt werden.

/edit2
Okay, wenn man bei dllwrap nun auch noch die Option --add-stdcall-alias benutzt, scheint alles zu funktionieren. :)

Aber mir wäre wohler, wenn mir jemand erklären könnte, was diese Option genau macht (oder einfach bestätigt, dass sie für genau soetwas da ist). :)


/edit 3 Zu früh gefreut.
Die DLL lässt sich zwar kompilieren und einbinden, aber sie funktioniert nicht richtig... spuckt ganz komische Ergebnisse aus, die überhaupt nicht nachzuvollziehen sind.
Ich nehme an, dass die Alias-Funktionen die restlichen Funktionen und Variablen benutzen und diese nicht kennen, weil sie keine Alias-Referenzen haben.
Aber die anderen Variablen und Funktionen tauchen in dem DEF-File gar nicht auf (weil sie halt nicht exportiert werden sollen). Entsprechend kann ich keine Alias-Namen setzen.
Mit ist aber aufgefallen, dass nicht alle Funktionen solche komischen Prä- und Postfixe haben. Ich hab aber keine Ahnung, wann das passiert. :(

/edit4
Okay, ein weiterer Nachtrag..
Ich habe noch weiter gesucht und habe gelesen, dass ich vor die Deklaration der Funktionen "extern "C"" setzen soll.
Das hat aber bei mir den gleichen Effekt wie ein Alias-Name in der DEF-Datei.
Der richtige Name wird gefunden, aber die Funktion, die man dann aufruft, macht Blödsinn.

Kann mir jemand erklären, was genau das "extern "C"" bewirkt?


/edit5
Okay, die Alias-Namen funktionieren doch... die "komischen Effekte" sind anders zu erklären.
Damit betrachte ich das Problem als gelöst.
 
Zuletzt bearbeitet:
Zurück