Discussion:
Bibliotheken - Datencontainer
(zu alt für eine Antwort)
jens kammer
2006-03-24 15:28:01 UTC
Permalink
Hallo,
ich möchte ein Programm schreiben, das mhrere Algorythmen berechnen kann,
die ich aber noch nicht alle kenne und auch erst noch entwickelt werden. So
dachte ich mir, mach das per Bibliotheken ( .dll , .so ) in denen jeweils
der aktuelle Algorythmus eingeladen werden soll. Soweit sogut, das nächste
Problem lies nicht lange auf sich warten, ich kenne nicht zwingend jetzt
schon die Parameter bzw rückgabewerte der Berechnungen. So habe ich eine
Abstrakte Klasse DatenContainer angelegt, die als Schnittstelle fungieren
soll:

class DatenContainer {
public: virtual ~DatenContainer() {}
};

Alle Datenklassen erben nun von dieser.
Die eingelesene Methode ist nach folgender Struktur aufgebaut:

DatenContainer* calculate(DatenContainer& dac){}

Da ich während der Programmierung der Bibliothek bereits weiss welche Daten
ich fordere und auch brauche kann ich mit einem dynamic-cast mir alles
passen zurechtlegen.
Soweit so gut. Funktionier auch alles ( unter Windows ).

Jetz mein Problem: das ganze muss auch auf Linux portabel sein, da schlägt
aber jedes mal er cast fehl ( Rückgabe 0 ) und ich bekomme
Speicherzugrifffehler.
Frage: Hat irgend jemand eine Idee an was das liegen kann und wichtiger
noch, wie kann ich es beheben, umgehen?

Zur weiteren Info wenn ich testhalber eine Methode calculate mit Paramether
einer Kopie einer Datenklasse nehme, habe ich die Daten. Also scheint das
Problem irgendwie an der Referenz zu liegen. Leider kann ich mit einer Kopie
von DatenContainer in der DLL auch nichts anfangen, weil ich dann kein
downcast mehr machen kann, oder geht das irgendwie?

Trotz des vielen Textes hoffe ich auf Hilfe,
Gruss
Jens Kammer
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+***@bud.prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-***@bud.prima.de
Thomas Maeder
2006-03-24 17:35:25 UTC
Permalink
Post by jens kammer
ich möchte ein Programm schreiben, das mhrere Algorythmen berechnen kann,
Algor*i*thmen
Post by jens kammer
die ich aber noch nicht alle kenne und auch erst noch entwickelt werden. So
dachte ich mir, mach das per Bibliotheken ( .dll , .so ) in denen jeweils
der aktuelle Algorythmus eingeladen werden soll. Soweit sogut, das nächste
Problem lies nicht lange auf sich warten, ich kenne nicht zwingend jetzt
schon die Parameter bzw rückgabewerte der Berechnungen. So habe ich eine
Abstrakte Klasse DatenContainer angelegt, die als Schnittstelle fungieren
class DatenContainer {
public: virtual ~DatenContainer() {}
};
Alle Datenklassen erben nun von dieser.
DatenContainer* calculate(DatenContainer& dac){}
Da ich während der Programmierung der Bibliothek bereits weiss
welche Daten ich fordere und auch brauche kann ich mit einem
dynamic-cast mir alles passen zurechtlegen. Soweit so
gut. Funktionier auch alles ( unter Windows ).
Jetz mein Problem: das ganze muss auch auf Linux portabel sein, da schlägt
aber jedes mal er cast fehl ( Rückgabe 0 ) und ich bekomme
Speicherzugrifffehler.
Frage: Hat irgend jemand eine Idee an was das liegen kann und wichtiger
noch, wie kann ich es beheben, umgehen?
Es hat viele Leute hier, aber Hellseher ist keiner, soviel ich weiss.
Poste hier doch mal das minimale Program, welches dieses Verhalten
hat.
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+***@bud.prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-***@bud.prima.de
jens kammer
2006-03-24 21:19:51 UTC
Permalink
class DatenContainer {

public: virtual ~DatenContainer() {}

};

class Scheduler{

typedef DatenContainer* (*rechenFunktion)(DatenContainer&);

public:

bool einlesen(char name[]);

DatenContainer* calculate(DatenContainer&);


private:

rechenFunktion tempCalculate;

}

// hier wird QT verwendet, macht aber keinen Unterschied zu dlopen etc. nur
brauche ich mir keine Gedanken machen unter welchen Betriebssystem ich bin
und ich spare die Präprozessor abfragen ( desweiteren bekomme ich an anderen
Stellen QT-Datentypen, so muss ich es sowieso einbinden). Der Fehler ist
auch ohne QT da.

bool Scheduler::einlesen(char name[]){

QLibrary myLib(name);

if ( myLib.isLibrary(name) || (!(name ==""))){

if ( myLib.load()){

this->tempCalculate = (rechenFunktion) QLibrary::resolve(name,"calculate");

}

}

myLib.unload();

}

---------------------------------------------------------------------

// Kommunikationslinien und Netzwerkstruktur erben von DatenContainer und
beinhalten dann Daten

int main (int argc, char** argv) {

Scheduler meinScheduler;

DatenContainer* dacP;


Netzwerkstruktur nwstr = ersteDatenEinlesen();

bool eingelesen = false;

eingelesen = meinScheduler.einlesen("d:/Algo1");

dacP = meinScheduler.calculate(nwstr);

eingelesen = meinScheduler.einlesen("d:/Algo2");

dacP = meinScheduler.calculate(dacP);

...

}

------------------------------------------------------------------

Aus dem Header des Algos:

extern "C" DatenContainer* calculate(DatenContainer&);

.cpp:

DatenContainer* calculate (DatenContainer& dac){

Kommunikationslinien* ausgabeDLL = new Kommunikationslinien();

DatenContainer* dacP;

dacP = &dac;

Netzwerkstruktur* nwstP;


if(dynamic_cast<Netzwerkstruktur*>(dacP))

nwstP = dynamic_cast<Netzwerkstruktur*>(dacP);

// ... Berechnung ...

return ausgabeDLL;

}

Ich hoffe die Ausschnitte reichen, ansonsten bitte nochmal melden.

Gruss

Jens Kammer
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+***@bud.prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-***@bud.prima.de
Olaf Krzikalla
2006-03-28 11:31:59 UTC
Permalink
Hi,

[Zitate mal umgestellt]
Post by jens kammer
extern "C" DatenContainer* calculate(DatenContainer&);
Mich wundert, dass der Compiler das frißt. C kennt AFAIK keine
Referenzen (AFAIK, weil ich C99 nicht genau kenne) und damit dürfte das
extern "C" hier äußerst problematisch sein.
Unabhängig davon schreibe ich die entsprechenden typedefs
Post by jens kammer
typedef DatenContainer* (*rechenFunktion)(DatenContainer&);
auch immer in den extern "C"-Bereich. Vermutlich macht es keinen
Unterschied, sicher bin ich mir aber nicht (wer weiß hier mehr?).
Post by jens kammer
bool Scheduler::einlesen(char name[]){
QLibrary myLib(name);
if ( myLib.isLibrary(name) || (!(name ==""))){
if ( myLib.load()){
this->tempCalculate = (rechenFunktion) QLibrary::resolve(name,"calculate");
}
}
myLib.unload();
--------------
Post by jens kammer
}
Das aber ist IMHO Dein eigentliches Problem. Du entlädst die Lib und
versuchst später, eine Funktion aus der Lib aufzurufen.
Post by jens kammer
Ich hoffe die Ausschnitte reichen, ansonsten bitte nochmal melden.
Ich hoffe, es reichte. Zumal ich hier eine Glaskugel habe, die mir
sagte, dass Netzwerkstruktur von DatenContainer abgeleitet ist.


MfG
Olaf Krzikalla
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+***@bud.prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-***@bud.prima.de
Andreas Huennebeck
2006-03-28 11:59:05 UTC
Permalink
Post by Olaf Krzikalla
Post by jens kammer
extern "C" DatenContainer* calculate(DatenContainer&);
Mich wundert, dass der Compiler das frißt. C kennt AFAIK keine
Referenzen (AFAIK, weil ich C99 nicht genau kenne) und damit dürfte das
extern "C" hier äußerst problematisch sein.
Nein. Das extern "C" ist nur eine Anweisung an den Compiler, das
Namemangling auszuschalten. Mit C-Code hat das erst mal nichts zu tun.
Als einziger mir bekannter Nachteil kann man solche Funktionen nicht
mehr überladen.

Tschau
Andreas
--
Andreas Hünnebeck | email: ***@gmx.de
----- privat ---- | www : http://www.huennebeck-online.de
Fax/Anrufbeantworter: 0721/151-284301
GPG-Key: http://www.huennebeck-online.de/public_keys/andreas.asc
PGP-Key: http://www.huennebeck-online.de/public_keys/pgp_andreas.asc
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+***@bud.prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-***@bud.prima.de
Stefan Reuther
2006-03-28 16:22:03 UTC
Permalink
Post by Andreas Huennebeck
Post by Olaf Krzikalla
Mich wundert, dass der Compiler das frißt. C kennt AFAIK keine
Referenzen (AFAIK, weil ich C99 nicht genau kenne) und damit dürfte das
extern "C" hier äußerst problematisch sein.
Nein. Das extern "C" ist nur eine Anweisung an den Compiler, das
Namemangling auszuschalten. Mit C-Code hat das erst mal nichts zu tun.
Als einziger mir bekannter Nachteil kann man solche Funktionen nicht
mehr überladen.
Doch, kann man. Aber es kann nur eine Funktion von den vielen 'extern
"C"' sein. Genauer gesagt, von allen gleichnamigen Funktionen in allen
Namensräumen darf nur eine 'extern "C"' sein.


Stefan
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+***@bud.prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-***@bud.prima.de
Rolf Magnus
2006-03-29 09:18:55 UTC
Permalink
Post by Andreas Huennebeck
Post by Olaf Krzikalla
Post by jens kammer
extern "C" DatenContainer* calculate(DatenContainer&);
Mich wundert, dass der Compiler das frißt. C kennt AFAIK keine
Referenzen (AFAIK, weil ich C99 nicht genau kenne) und damit dürfte das
extern "C" hier äußerst problematisch sein.
Nein. Das extern "C" ist nur eine Anweisung an den Compiler, das
Namemangling auszuschalten.
Das mag eine gängige Variante sein, aber muß nicht. extern "C" schaltet
zunächst mal auf "C linkage" um, also die Linkage, die vom C-Compiler
genutzt wird, so dieser vorhanden. Das beinhaltet typischerweise die
Namensgebung und die Aufrufkonventionen (Art der Parameterübergabe u.s.w.).
Aber wie ist die korrekte Art, in "C linkage" einen Parameter eines
Referenztyps zu übergeben, wenn es in C gar keine Referenzen gibt?
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+***@bud.prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-***@bud.prima.de
jens kammer
2006-03-28 15:00:13 UTC
Permalink
Post by Olaf Krzikalla
Das aber ist IMHO Dein eigentliches Problem. Du entlädst die Lib und
versuchst später, eine Funktion aus der Lib aufzurufen.
Ja, das mache ich, aber selbst wenn sie noch geladen ist funtioniert es
nicht. Was mich aber wesentlich mehr verwundert, dass genau dieser Code
unter Winows funktioniert und unter Linux nicht. Hat da irgenjemand eine
Idee an was das liegen könnte? Oder eine Idee wie ich das ganze
implementieren kann, das es läuft?
Post by Olaf Krzikalla
Zumal ich hier eine Glaskugel habe, die mir sagte, dass Netzwerkstruktur
von DatenContainer abgeleitet ist.
Naja, das hatte ich in dem zweiten Beitrag geschrieben, egal.


Gruss
Jens Kammer
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+***@bud.prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-***@bud.prima.de
Loading...