Ableiten von Klasse in shared library



  • Hallöle,

    Ich habe eine Klasse foo mit einer pure virtual Methode bar. In einer shared library möchte ich von foo eine Klasse baz ableiten, die bar Überschreibt. Leider kriege ich Linkerfehler beim builden der Lib.

    So habe ich es probiert...

    Programm:

    struct foo
    {
    	virtual void bar() = 0;
    	virtual ~foo() {}
    };
    

    Shared Library:

    struct foo
    {
    	virtual void bar();
    	virtual ~foo();
    };
    
    struct baz : foo
    {
    	virtual void bar()
    	{
    		std::cout << "Hello, World!\n";
    	}
    };
    
    extern "C" std::unique_ptr<foo> create_foo()
    {
    	return std::unique_ptr<foo>(new baz);
    }
    

    Fehlermeldungen vom Linker:

    Undefined symbols:
    "typeinfo for foo", referenced from:
    typeinfo for baz in main.o
    "vtable for foo", referenced from:
    foo::foo() in main.o
    "foo::~foo()", referenced from:
    baz::~baz() in main.o
    ld: symbol(s) not found

    Grüße,
    PI



  • Okay, irgendwie logisch, dass der Linker die Funktionen nicht findet. Aber es kann doch wohl kaum der Sinn von shared libraries sein, alle Definitionen in die Lib nochmal zu stecken, um in der Binary Code zu duplizieren?



  • Es wäre hilfreich, wenn du dich verständlich ausdrücken würdest. Meine Interpretation in eckigen Klammern:

    314159265358979 schrieb:

    Ich habe [in einem Programm] eine Klasse foo mit einer pure virtual Methode bar. In einer shared library [die vom Programm benutzt wird] möchte ich von foo [die im Programm definiert ist] eine Klasse baz ableiten [die in der Programmbibliothek definiert und vom Programm benutzt wird] [...]

    Bei dir steht die Programmbibliothek also nicht für sich alleine sondern muss gegen das sie benutzende Programm gelinkt werden. Dann steht sie aber nicht mehr für sich alleine, zwei unterschiedliche Programme können also nicht die gleiche so-Datei benutzen -- wozu da eine shared library? Dir wäre mit einer static library besser geholfen, aber das Design ist und bleibt ein WTF.



  • Deine Interpretationen sind richtig. Ich möchte aus der Library Funktionen des Programms aufrufen. Woran ich beim erstellen des Threads gar nicht gedacht habe: Das Problem ist nicht speziell im Zusammenhang mit Klassen. Also nochmal allgemeiner gefragt: Wie kann ich innerhalb der Library Funktionen des Programms aufrufen?

    An dem Design ist nichts falsch, ich möchte innerhalb der Libs Daten aus dem Programm holen können, um sie zu verarbeiten. Die Ergebnisse möchte ich dann wieder an das Programm übergeben. Ich habe mir das in etwa so vorgestellt:
    1.) Das Programm informiert die Lib, dass ein gewisses Event eingetreten ist, indem es irgendein Callback aufruft.
    2.) Die Lib kann sich über verschiedenste getter alle Daten holen, die sie braucht.
    3.) Die Lib ruft ggf. eine Funktion des Programms auf, um Aktionen ausführen zu können.

    Das ganze soll eine Art Plugin-System werden.



  • mit -rdynamic linken



  • Und im Code reichen dann Deklarationen der Funktionen aus?



  • ja



  • g++: error: unrecognized command line option '-rdynamic'

    😞



  • -Wl,-rdynamic



  • Bekomme dennoch die Linkerfehler.

    "typeinfo for foo", referenced from:
    g++ -dynamiclib -o "libtestdll" ./main.o
    typeinfo for baz in main.o
    "vtable for foo", referenced from:
    foo::foo() in main.o
    "foo::~foo()", referenced from:
    baz::~baz() in main.o
    ld: symbol(s) not found



  • nimm am besten cmake... das macht rdynamic automatisch dazu. wenns dann immer noch nicht geht stimmt doch was mit dem code nicht



  • Ich benutze make, weil meine IDE automatisch makefiles für mich erstellt. Kompilieren und Linken ist hier getrennt. Meine Flags sehen so aus:

    g++ -O0 -g3 -Wall -c -fmessage-length=0 -std=c++11 -Wl,-rdynamic -fPIC -MMD -MP -MF"main.d" -MT"main.d" -o "main.o" "../main.cpp"

    g++ -dynamiclib -o "libtestdll" ./main.o



  • das flag muss beim linken angegeben werden. Beim Programm und/oder bei der Library.



  • Dann kriege ich wieder die "unknown option"-Fehlermeldung. Kann es sein, dass der MacPorts GCC 4.7 unter Mac OS X dafür ein anderes Flag hat?



  • haste jetzt wieder das -Wl weggelassen?
    ich kenne mac os nicht.



  • Nein, habe ich nicht.



  • Wieso übergibst du nicht einfach an die Shared Lib Pointer der Funktionen im Hauptprogramm, die du innerhalb der Shared Lib verwenden willst?


Anmelden zum Antworten