Forum: PC-Programmierung DLL in C++ schreiben


von peterguy (Gast)


Lesenswert?

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
von Mathias R. (prinz77) Benutzerseite


Lesenswert?

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

von Peter (Gast)


Lesenswert?

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.

von Klaus W. (mfgkw)


Lesenswert?

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
Noch kein Account? Hier anmelden.