DLL's und Klassen

Du bist neu in der Welt von C++? Dann schau hier herein!
Antworten
graythornAK
Beiträge: 29
Registriert: 16. März 2007 15:14

DLL's und Klassen

Beitrag von graythornAK »

Hallo zusammen,

ich möchte eine dll erstellen und dort eine Klasse exportieren. Mit Funktionen klappt alles prima, bei Klassen bekomme ich einen Linkerror.

Hier ist mein Code

die Header-Datei der DLL:

Code: Alles auswählen

#ifdef BUILD_DLL
	#define EXPORT __declspec(dllexport)
#else
	#define EXPORT __declspec(dllimport)
#endif

extern "C"
class EXPORT CAdder
{
	public:
		CAdder();
		~CAdder();

		int  AddN(int iValue, int iN);
}; // class CAdder
die cpp-Datei der DLL:

Code: Alles auswählen

#include <stdio.h>
#include "example_dll.h"

CAdder::CAdder()                            { ; }
CAdder::~CAdder()                          { ; }
int  CAdder::AddN(int iValue, int iN)   { return iValue + iN; }
Ich benutze MinGW, das Program wird problemlos compiliert und die addTest.dll wird erzeugt :)


Das Programm, welches die DLL benutzt lautet

Code: Alles auswählen

int main ()
{
	//Windows handl
	HINSTANCE hdll;

	// LoadLibrary
	hdll = LoadLibrary("addTest.dll");

	CAdder	a;
	printf("--> 6 + 10 = %d\n", a.AddN(6, 10));

	return 0;
} // main

Die Fehlermeldung des Linkers lautet:

Code: Alles auswählen

C:/Workspace/dllTest/Debug/../hello.cpp:40: undefined reference to `_imp___ZN6CAdderC1Ev'
C:/Workspace/dllTest/Debug/../hello.cpp:41: undefined reference to `_imp___ZN6CAdder4AddNEii'
C:/Workspace/dllTest/Debug/../hello.cpp:43: undefined reference to `_imp___ZN6CAdderD1Ev'
C:/Workspace/dllTest/Debug/../hello.cpp:43: undefined reference to `_imp___ZN6CAdderD1Ev'
[/color]Weiß jemand Rat :?:

Danke und Gruß
Andreas
Zuletzt geändert von graythornAK am 27. November 2009 13:21, insgesamt 1-mal geändert.
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

Gute Idee: Name mengling ausschalten wenn man Funktionen aus ner Dll exportiert!
schlechte Idee: Name mengling ausschalten, wenn klassendefinitionen bei den parametern auftauchen ^^

meinst nicht, dass sich
extern "C"
und class bissi beissen ? :-)

lass das extern C weg !
wenn du klassen exportierst, wird deine Dll soweiso compiler, compiler flag und mondscheinphasenabhaengig. Da kannst ned viel gegen machen ....

CAdder::CAdder() { ; }
Das hab ich so auch noch ned gesehen ^^ Man lernt immer wieder neue Dinge , hehe. Das arme Semikoleon :-)

Ciao ...
graythornAK
Beiträge: 29
Registriert: 16. März 2007 15:14

Beitrag von graythornAK »

meinst nicht, dass sich
extern "C"
und class bissi beissen ? Smile
Ich bin mir nicht ganz sicher ob die sich beißen, aber wenn ich das
extern "C"
weglasse ist das Ergebnisse exakt das gleiche wie mit.....
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Code: Alles auswählen

nt main ()
{
   //Windows handl
   HINSTANCE hdll;

   // LoadLibrary
   hdll = LoadLibrary("addTest.dll");

   CAdder   a;
   printf("--> 6 + 10 = %d\n", a.AddN(6, 10));

   return 0;
} // main 
Sorry, aber was soll das LoadLibrary hier? Du musst schon gegen die Library linken.. Ein dynamisches Laden zur Laufzeit bringt rein gar nicths.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
graythornAK
Beiträge: 29
Registriert: 16. März 2007 15:14

Beitrag von graythornAK »

Es ist doch gerade der Sinn einer dynamischen Library, das sie zur laufzeit geladen wird!

Es geht im Endeffekt darum, ein Plugin für ein Program zu schreiben. Dieses wird dann zum Program kopiert, von diesem geladen und eben benutzt.

Beispiel: Photoshop-Plugins oder Plugins für Gimp. Das ermöglicht anderen herstellern solche Module anzubieten. Diese können dann natürlich nicht gegen das Program gelinkt werden, und dafür gibt es eben die dll (heißt ja auch dynamische link library, also zur Luafzeit hinzugelinkt)
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

Sorry, aber was soll das LoadLibrary hier? Du musst schon gegen die Library linken.. Ein dynamisches Laden zur Laufzeit bringt rein gar nicths.
Ich denk das ist genau das was er nicht will ^^

@graythornAK

du exportierst mit sicherheit deine CAdder.h
das heisst, die exe und die dll kennen die deklaration.
implementieren tust die die CAdder aber nur in der dll oder ? Also nur die dll iss gegen die CAdder.cpp -> CAdder.o gelinkt.

Das heisst nur die Dll, also der code in der DLL kann instanzen von Cadder erstellen. die exe kann nur methoden drann aufrufen.

Also musst Du dir ne create (und destroy) oder get Funktion schreiben .... wo dir ein in der DLL angelegtes object holen kannst (get = global in der dll, solange gueltig wie die dll lebt, create/destroy = dynamsich)
oder du machst die Implementation auch in der exe zugaenglich, womit aber ein Aspekt der dll verschwindet (beide binaries muessen das selbe implementieren). Macht man ueblicher weisse nur bei kleinen kommunikationsObjecten.
Das beidseitige importieren macht man am besten ueber importlibs dann, wie christian es vorgeschlagen hat ....

Ciao ....
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

graythornAK hat geschrieben:Es ist doch gerade der Sinn einer dynamischen Library, das sie zur laufzeit geladen wird!

Es geht im Endeffekt darum, ein Plugin für ein Program zu schreiben. Dieses wird dann zum Program kopiert, von diesem geladen und eben benutzt.

Beispiel: Photoshop-Plugins oder Plugins für Gimp. Das ermöglicht anderen herstellern solche Module anzubieten. Diese können dann natürlich nicht gegen das Program gelinkt werden, und dafür gibt es eben die dll (heißt ja auch dynamische link library, also zur Luafzeit hinzugelinkt)
Da hast du was missverstanden: Die zahlreichen DLLs auf deinem Windows-System sind zu 99% keine Plugins (optional), sondern gelinkte (vorgeschriebene) Bibliotheken. Der Vorteil darin besteht, dass diese Bibliotheken ausgetauscht werden können. So können beispielsweise Fehler in Qt-Bibliotheken (z.B. libQtCore.dll) behoben werden, ohne dass ein Qt-Programm neu erstellt werden muss.

Ein Plugin ist nun einfach eine besondere(!) Anwendung einer dynamischen Library. In deinem Ursprungpost beschreibst du nicht, was du möchtest. Und der Code hat Hinweise auf beide Varianten ("CAdder a;" -> normale Bibliothek, "LoadLibrary()" -> Plugin) . Daher der Hinweis von Christian81.

Noch als Ergänzung zu den Infos von RHBaum: Plugins benötigen ein festgelegtes Interface. Überlege dir also eine Basisklasse, welche die unterschiedlichen Plugins dann Implementieren können:

Code: Alles auswählen

  // in der Anwendung:
  AbstractPlugin *plugin = create(); // siehe RHBaum
  ...

  // im Plugin:
 AbstractPlugin *create(){
    return new KonkretesPlugin();
 } 
Weil "LoadLibrary" nichts mit C++-Grundlagen zu tun hat erlaube ich mir noch folgenden Hinweis: Wir sind in einem Qt-Forum. Falls das eine Qt-Applikation wird, solltest du QPluginLoader verwenden.
Antworten