PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C++ und Shared Lib



Morfio
21-03-2005, 15:07
Hi,

ich versuche mich gerade in der Library-Erstellung, was mit C anscheinend kein Problem ist. Allerdings habe ich grosse Probleme, in C++ auf Klassen zuzugreifen, die in den .so-Dateien implementiert sind. Quasi geht es überhaupt nicht (:.

Ich denke, es fehlt einfach eine Vorwärtsdeklaration ... aber ich kann ja nicht die Prototypen der Klasse einbauen. Nehmen wir mal meine folgende (Meister-) Klasse:


#include <iostream>

class meineKlasse {

public:
meineKlasse();
~meineKlasse();
void printHello();

};

Die die folgende Implementation besitzt:


#include "meineklasse.h"

meineKlasse::meineKlasse() {
}

meineKlasse::~meineKlasse() {
}

void meineKlasse::printHello() {
printf("Hello World");
}

Alles soweit recht einfach und plain. Mit folgenden Befehlen kompiliere ich die zu einer Shared Library:

c++ -fPIC -c meineklasse.cpp
c++ -shared -Wl,-soname,libmeineklasse.so.0 -o libmeineklasse.so.0.0 meineklasse.o-lc

Das funktioniert auch ganz ohne Fehlermeldung.

Wenn ich jetzt aber damit in meiner main.cpp arbeiten möchte:


class meineKlasse;

int main() {

meineKlasse mk;

return 0;

}

und das so kompiliere:

c++ main.cpp -lmeineklasse

kommt der folgende Fehler:


main.cpp: In function `int main()':
main.cpp:5: error: aggregate `meineKlasse mk' has incomplete type and cannot be
defined

Die Shared Lib liegt unter /usr/local/lib und ldconfig habe ich danach auch ausgeführt, ohne das er meckerte.

Vllt. weiss hier noch jemand, was falsch laufen könnte (ist bestimmt nur eine Kleinigkeit) ... im Internet finde ich nur, wie ich C-Shared-Libs unter C++ nutze ...

Vielen Dank,

Morfio ...

locus vivendi
21-03-2005, 15:54
Du musst die Klassendefinition (das ist das "class XXX { ... };") in jeder Übersetzungseinheit einbinden (typischerweise per #include) in der du die Klasse verwendest. Nur in Ausnahmefällen reicht die Vorwärtsdefinition aus.

Vielleicht ist es das Beste, wenn du auch ein C++-Buch oder -Tuturial konsultierst.

f0rtex
21-03-2005, 19:06
Das [1] C++-dlopen-mini-Howto ist ein guter Einstieg.

MfG
f0rtex

[1] http://www.isotton.com/howtos/C++-dlopen-mini-HOWTO/C++-dlopen-mini-HOWTO.html

Morfio
22-03-2005, 06:49
@locus vivendi


Vielleicht ist es das Beste, wenn du auch ein C++-Buch oder -Tuturial konsultierst.

Das ist ja das Dumme. Ich habe hier etliche Bücher (C++), in denen das lustigerweise nur für C steht. Und im Internet habe ich überhaupt nichts dazu gefunden, sonst hätte ich ja nicht gefragt.


@f0rtex


Das [1] C++-dlopen-mini-Howto ist ein guter Einstieg.

Vielen Dank, das sieht schonmal sehr sehr gut aus. Werde ich nachher mal durchlesen.

Morfio ...

RapidMax
22-03-2005, 11:25
Hier gibt es keine Unterschiede zu C: Auch in C musst du die Prototypen deklarieren, was üblicherweise durch das Einbinden von Header-Dateien geschieht, aber nicht unbedingt so erfolgen muss. Eine Klassendeklaration ist nichts anderes. Schliesslich musst du auch structs in C so angeben.
Beispiel gefällig? (nur Schematisch):

header.h:
class Foo {
public: int doSomething();
}

library.c:
#include "header.h"
int Foo::doSomething() { return 42; }

main.c:
#include "header.h"
int main() {
Foo f;
f.doSomething();
return 0;
}

$ gcc -shared -o library.so library.c
$ gcc -lrary -o program main.c

Sei noch zu erwähnen, dass die Bindings von C++ anders als in C sind. Wenn aus C++ heraus Funktionen in C-Bibliotheken aufgerufen werden, müssen diese daher als "extern C" deklariert werden.

Morfio
22-03-2005, 14:12
Ach, ok, jetzt habe ich verstanden, was Du meinst. Vielen Dank ...!

anda_skoa
22-03-2005, 16:13
Das [1] C++-dlopen-mini-Howto ist ein guter Einstieg.


Für den Fall das er mal später dlopen benutzen will :)

Das Problem war ja bereits ein Compilerfehler (vergessenes include)

Ciao,
_