Samstag, 26. März 2011

C/C++: DLL aus EXE in MS VS 2005 (Tutorial)

Einleitung


Das ist eines meiner alten Tutorials, kopiert von hier.

Da alle grösseren Games in mehrere .dll's und eine kleine .exe aufgeteilt sind, möchte ich hier ein kleines Tutorial geben, wie man aus einer bestehenden Konfiguration (EXE) in Visual Studio 2005 eine DLL macht. (Ich habe dieses Tutorial speziell für Microsofts Visual Studio 2005 C++ geschrieben.)

Dlls sind guut. ;) Sie lassen das Ganze zwar unübersichtlicher aussehen, dafür kann man dann einfacher patchen. Der End-User muss sich nur eine kleine 300kb-.dll runterladen, wenn z.B. beim Sound was geändert wurde..und nicht die ganze 124Mb-.exe.

ToDo's

- Ladet erstmal das Projekt ganz normal.
- Geht dann zu Project->(Projektname) Properties
- Dort in der Configurations-Kombobox "All Configurations" auswählen.
- Dann nach Configuration Properties->General
- Dort bei Configuration Type den Eintrag "Dynamic Library (.dll)" auswählen.

Jetzt kommt die Arbeit: Erstmal müsst ihr die Entry-Funktion entfernen (main oder WinMain). Meine Projekte sind darum so aufgebaut, dass ich einfach die "Main.cpp" aus dem Solution-Explorer löschen kann.
Jetzt sollten nur noch die Funktionen, Variablen, Klassen und was auch immer ihr in die .dll packen wollt, übrig sein. Jede Funktion, Variable etc. welche ihr AUSSERHALB der .dll benutzen wollt, muss das da davor haben:

_declspec(dllexport)
bzw.
_declspec(dllimport)

Zum Beispiel:

_declspec(dllexport) void MyFunc(void) {..};
_declspec(dllexport) int MyInt;
_declspec(dllexport) class A {...};

etc.

Das muss nur in den jeweiligen Header-Dateien geschrieben werden.

dllEXport ist nur für die DLL selbst wichtig. Die mitgelieferte Header-Datei für den End-User braucht dllIMport.

Man muss deshalb zwei Header-Dateien erstellen, die genau dasselbe enthalten bis auf dll-ex/im-port. Die eine (import) wird dann mitgeliefert, und die andere (export) wird in den eigenen .cpp Dateien ge-included. Die End-User-Header kann sogar anders heissen als die ge-includete.

Funktionen, Variablen etc. die nur INNERHALB der .dll benutzt werden, brauchen dies nicht.
Wie oben schon gesagt, braucht Ihr eine Header-Datei, wo alle diese _declspec(dllexport) Sachen nochmal definiert sind. Vergesst das extern bei Variablen nicht! (Bsp: extern _declspec(dllexport) int myint;) - Ah ja: Vergesst die Variablen selbst nicht, darum erwähne ich dies noch mal.

So jetzt könnt ihr das kompilieren.

Um das ganze zu testen, einfach eine neue .exe-Applikation erstellen, die .lib, die .dll und die import-Header-Datei ins neue Verzeichnis kopieren und in der Main.cpp dann ein #include "MyDllHeader.h" geben.

(Darauf achten, dass die .cpp's von der dll nicht in diesem Verzeichnis sind. Könnte eventuell zu Komplikationen kommen...)

Dann müsst Ihr noch bei den Project Properties im Linker Abschnitt bei Additional Dependencies eure .lib eintragen.

Nun könnt ihr die _declspec(dllimport)-Funktionen / Variablen etc. ganz normal benutzen.

So, das wars. Wenns nicht geht, muss eventuell noch der Library-Pfad vom Visual Studio erweitert werden. (Oder die erstellte .lib ins lib-Verzeichnis vom Visual Studio kopieren.)

Achtung: Resourcen werden nicht mit reinkompiliert in die .dll. Die müsst ihr noch dazu liefern. (Das .rc File und resources.h) - Achtet dabei darauf, dass die Resourcen-ID's nicht geändert werden. Die resource.h wird ja noch ins .dll file reinkompiliert...also ich weiss nicht ob das was ausmacht, ich denke aber schon.

Keine Kommentare:

Kommentar veröffentlichen