Hallo Forum, ich möchte eine DLL erstellen mit C++ (nicht C). Habe mir die Visual Studio 2008 C+++ Express Edition besorgt und erste Gehversuche unternommen. Vom Prinzip her klappt die erste Version der DLL, aber ich bin mit dem Code an sich ziemlich unzufrieden. Da ich in der Objektorientierten Welt noch neu bin (bisher nur strukturiert programmiert), tue ich mich mit dem Programieren unter C++ recht schwer. Hat vielleicht jemand schon mal eine kleine DLL in C++ geschrieben und würde den Sourcecode hier veröffentlichen? Es geht mir darum, ein paar Ideen / Inspirationen zu bekommen, deswegen ist es eigentlich egal was die DLL macht. Also, immer her mit eurem Beispielcode :-)
:
Verschoben durch Moderator
Gugst du hier -> www.sourceforge.net Ich würde mal sagen da dümpeln mehr als genug DLL's rum. Ob die nun gut oder schlecht programmiert sind liegt wohl im Auge des Betrachters. :D
ich versteh nicht ganz wo das Problem liegt. ob das ganze in einer Dll ist oder nicht spielt doch keine Rolle. Hast du generell ein Problem bei der Programmierung in C++ oder willst du die Dll Dynmisch laden? Wenn du sie dynamsich laden willst, macht du am besten eine C schnittstelle und verwendest einfach eine C funktion die dir ein object zurück gibt. object x = (dll).GetObject() danach kannst du mit x alles machen was c++ erlaubt.
Wenn du objektorientiert und DLLs zusammenbringen willst, dann hier was zum Probieren: Es gibt ein Hauptprogramm, das zu einer EXE wird und nur eine Basisklasse kennt (Base). Eine abgeleitete Klasse Derived (dem Hauptprogramm gänzlich unbekannt) wird in einer DLL (bzw. "shared object" in Linux) definiert. Das Hauptprogramm lädt die DLL, holt sich über eine create()-Funktion wie von Peter vorgeschlagen ein Objekt der abgeleiteten Klasse und ruft daraus eine Methode auf, obwohl Derived ihm unbekannt ist. Sinnvollerweise würde man Base auch gleich in einer DLL ablegen, weil es so wie hier gezeigt sowohl zur EXE als auch zur DLL gelinkt werden muß, aber das ist mir jetzt zuviel Aktion. Die DLL mit Base würde man zum Hauptprogramm ebenso wie zur Derived-DLL statisch linken, also nicht dynamisch zur Laufzeit holen. Das Hauptprogramm:
1 | // Time-stamp: "17.08.09 10:07 dll_dynload_base.cpp klaus?wachtler.de"
|
2 | //
|
3 | // Beispiel für die Verwendung einer DLL, die eine Ableitung
|
4 | // definiert.
|
5 | //
|
6 | // In diesem Quelltext wird die Basisklasse verwendet, eine DLL
|
7 | // dynamisch geladen in der davon eine Ableitung definiert ist und ein
|
8 | // derartiges Objekt erzeugt wird.
|
9 | //
|
10 | // Kompilieren unter Linux:
|
11 | // g++ -Wall dll_dynload_base.cpp Base.cpp -ldl -o dll_dynload_base
|
12 | //
|
13 | // Aufruf unter Linux (funktioniert nur, wenn auch Derived.plugin_so bereits
|
14 | // erzeugt wurde, siehe Derived.cpp):
|
15 | // ./dll_dynload_base
|
16 | //
|
17 | // Kompilieren unter Windows mit VC++ VS2005:
|
18 | // cl /EHsc dll_dynload_base.cpp Base.cpp
|
19 | //
|
20 | // Aufruf unter Windows (funktioniert nur, wenn auch
|
21 | // Derived.plugin_win bereits erzeugt wurde, siehe Derived.cpp):
|
22 | // dll_dynload_base.exe
|
23 | |
24 | #include <iostream> |
25 | |
26 | #include "Base.h" |
27 | |
28 | |
29 | #if defined __GNUC__
|
30 | #include <dlfcn.h> |
31 | #elif defined _WIN32
|
32 | #include <windows.h> |
33 | #include <winuser.h> |
34 | #endif
|
35 | |
36 | |
37 | |
38 | int main( int nargs, char **args ) |
39 | {
|
40 | // Base ist hier bekannt, kann direkt verwendet werden:
|
41 | Base einBase( 25 ); |
42 | einBase.tuwas(); |
43 | |
44 | // Ein Derived-Objekt kann über die DLL angesprochen werden:
|
45 | |
46 | #if defined __GNUC__
|
47 | // DLL laden, Linux-Version:
|
48 | void *plugin_handle = dlopen( "./Derived.plugin_so", RTLD_NOW ); |
49 | #elif defined _WIN32
|
50 | // DLL laden, Windows-Version:
|
51 | HINSTANCE plugin_handle = LoadLibrary( ".\\Derived.plugin_win" ); |
52 | #endif
|
53 | if( !plugin_handle ) |
54 | {
|
55 | std::cerr << "kann Plugin nicht laden" << std::endl; |
56 | }
|
57 | else
|
58 | {
|
59 | // Typ der create()-Funktion:
|
60 | typedef Base*(*plugin_create_fp_t)(); |
61 | #if defined __GNUC__
|
62 | // Zeiger auf create() holen, Linux-Version:
|
63 | plugin_create_fp_t plugin_create_fp = (plugin_create_fp_t)dlsym( plugin_handle, |
64 | "create"
|
65 | );
|
66 | #elif defined _WIN32
|
67 | // Zeiger auf create() holen, Windows-Version:
|
68 | plugin_create_fp_t plugin_create_fp |
69 | = (plugin_create_fp_t)GetProcAddress( plugin_handle, |
70 | "create"
|
71 | );
|
72 | #endif
|
73 | |
74 | if( !plugin_create_fp ) |
75 | {
|
76 | std::cerr << "Funktion nicht in DLL gefunden" << std::endl; |
77 | }
|
78 | else
|
79 | {
|
80 | // Objekt der abgeleiteten Klasse Derived über die create()-Funktion
|
81 | // erzeugen lassen:
|
82 | Base *p_Object = plugin_create_fp(); |
83 | |
84 | p_Object->tuwas(); |
85 | |
86 | delete p_Object; p_Object = NULL; |
87 | }
|
88 | |
89 | |
90 | // DLL wieder freigeben:
|
91 | plugin_create_fp = NULL; |
92 | #if defined __GNUC__
|
93 | dlclose( plugin_handle ); |
94 | #elif defined _WIN32
|
95 | FreeLibrary( plugin_handle ); |
96 | #endif
|
97 | plugin_handle = NULL; |
98 | |
99 | }
|
100 | |
101 | return 0; |
102 | }
|
Die Basisklasse
1 | // Time-stamp: "17.08.09 08:27 Base.h klaus?wachtler.de"
|
2 | //
|
3 | // Eine Basisklasse als Beispiel...
|
4 | |
5 | class Base |
6 | {
|
7 | public:
|
8 | |
9 | Base( int wert = 0 ); |
10 | |
11 | virtual ~Base(); |
12 | |
13 | virtual void tuwas(); |
14 | |
15 | protected:
|
16 | int wert; |
17 | };
|
Ihre Implementation:
1 | // Time-stamp: "17.08.09 08:14 Base.cpp klaus?wachtler.de"
|
2 | //
|
3 | // Implemenation der Basisklasse
|
4 | |
5 | #include <iostream> |
6 | |
7 | #include "Base.h" |
8 | |
9 | Base::Base( int wert ) |
10 | : wert( wert ) |
11 | {
|
12 | }
|
13 | |
14 | Base::~Base() |
15 | {
|
16 | }
|
17 | |
18 | void Base::tuwas() |
19 | {
|
20 | std::cout << "ich bin ein Base, mein Wert ist " << wert << std::endl; |
21 | }
|
Die DLL mit der abgeleiteten Klasse:
1 | // Time-stamp: "17.08.09 10:02 Derived.cpp klaus?wachtler.de"
|
2 | //
|
3 | // Quelltext einer DLL, die von Base die Klasse Derived ableitet und
|
4 | // eine Funktion create() definiert, mit der ein Objekt von Derived
|
5 | // erzeugt werden kann.
|
6 | //
|
7 | // Kompilieren unter Linux:
|
8 | // g++ -shared Derived.cpp Base.cpp -fpic -o Derived.plugin_so
|
9 | //
|
10 | // Kompilieren unter Windows mit VC++ VS2005:
|
11 | // cl /EHsc /LD Derived.cpp Base.cpp /FeDerived.plugin_win
|
12 | |
13 | #include <iostream> |
14 | |
15 | #include "Base.h" |
16 | |
17 | class Derived: public Base |
18 | {
|
19 | public:
|
20 | Derived( int wert = 0 ) |
21 | : Base( wert ) |
22 | {
|
23 | }
|
24 | |
25 | virtual void tuwas() |
26 | {
|
27 | std::cout << "ich bin ein Derived, mein Wert ist " << wert << std::endl; |
28 | }
|
29 | |
30 | virtual ~Derived() |
31 | {
|
32 | }
|
33 | |
34 | };
|
35 | |
36 | |
37 | extern "C" |
38 | #ifdef _WIN32
|
39 | __declspec(dllexport) |
40 | #endif
|
41 | Base * create() |
42 | {
|
43 | return new Derived(); |
44 | }
|
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.