Warum kann ich nicht verknüpfen eines gemischten C/C++ statische Bibliothek, die eine C-Schnittstelle mit gcc?
Habe ich ein gemischtes C/C++ - Bibliothek.
Außen stellt eine C-Schnittstelle mittels extern C. Intern gibt es Vorlagen und Klassen. Die Erstellung der Bibliothek mit "ar" stellte keine Probleme. Die Datei heißt libo-client.ein.
Jedoch, wenn die Verknüpfung der .a
Datei mit gcc (nicht g++) bekomme ich viele Fehler, die wie folgt Aussehen:
libo-client.a(mysocket.o):(.rodata._ZTV7mStream[vtable for mStream]+0x10): undefined reference to `__cxa_pure_virtual'
...
mysocket.cpp:(.text+0x15ad): undefined reference to `operator new[](unsigned long)'
mysocket.cpp:(.text+0x15c1): undefined reference to `operator delete(void*)'
mysocket.cpp:(.text+0x167a): undefined reference to `__cxa_allocate_exception'
mysocket.cpp:(.text+0x16a6): undefined reference to `__cxa_throw'
...
Meine compile - /link-Zeile sieht wie folgt aus:
gcc $(CFLAGS) $(INCLUDES) test2.c libo-client.a -o test2
Wo test2 ist meine Testumgebung.
Dieses problem tritt nicht auf, wenn ich mit g++. Allerdings werde ich, um Schnittstelle dieser Bibliothek in C-Projekt kompiliert mit gcc. Wie bekomme ich dieses? Was ist die Ursache davon?
EDIT:
Obwohl ich nicht die standard-C++ - Bibliothek, es ist offensichtlich benötigen einige Dinge, die like-operator new/delete etc. und es gibt Ausnahmen intern.
Ich verlinkt bin, dieses Ding gegen den Xen-hypervisor, also bin ich nicht sicher, welche Optionen ich habe aber völlig umschreiben diese Sache oder vielleicht versuchen, kompilieren von Xen mit G++ statt?
- So dass es eine dynamische Bibliothek könnte auch helfen. Haben Sie schaute in das überhaupt?
- Danke Chris. Das funktioniert tatsächlich als ein dynamic shared object.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Der einfachste Weg, um dein problem ist es, eine Verknüpfung mit
g++
; diese ruft die richtigen Bibliotheken im Ort.Das problem ist, dass C++ hat eine Menge von Anforderungen, C nicht, und macht mehr Arbeit vor dem Aufruf
main()
um sicherzustellen, dass die Dinge richtig initialisiert.Wenn Sie darauf bestehen, über die Verknüpfung mit dem C-compiler, zumindest müssten Sie umfassen die Unterstützung für C++ - Bibliothek, mit Ihrem link-Befehl.
${CXX}
. Wo der C-compiler istgcc
der C++ - compiler ist in der Regelg++
. Wo Sie sind mit verschiedenen Compilern, Sie noch den link mit dem C++ - compiler wurde genutzt, um die C++ - Objekt Module.Ihre C++ - Bibliothek ist immer noch eine C++ - Bibliothek intern, was bedeutet, dass es enthält externe Verweise auf die verschiedenen housekeeping-Funktionen aus C++ - standard-Bibliothek. Um zu beheben diese links müssen Sie link Ihre endgültige ausführbare Datei für C++ - standard-Bibliothek.
gcc
nicht tun es für Sie automatisch. Entweder explizit Versorgung der C++ - standard-Bibliothek zugcc
oder verwendeng++
compiler statt.Archiv ist nur noch ein Haufen von Objekt-Dateien (.o), so, wenn die Verknüpfung zu einer ausführbaren Datei oder shared library, die Sie noch brauchen, um die Verknüpfung mit
g++
zu beheben Symbole der C++ - runtime (wie die, sobald Sie sehen, in Ihre Fehlermeldungen).Für Ihre C-Funktionen haben C linkage, sollte es genug, um wickeln Sie Sie in
extern "C"
Blöcke. Könnten sich die Dinge noch komplizierter, wie z.B. Windows, mit seinen Myriaden von linkage-Makros (STDCALL, WINAPI, etc.) erweitern auf andere Sachen (einige compiler-spezifisch) wie __stdcall, __declspec(export), etc.Fehler, die Sie sehen, scheinen aufgrund der fehlenden Verknüpfung zu Standard-C++ - Bibliothek, die das symbol definition für neue operator, operator delete etc. Versuchen Sie die Verknüpfung
stdc++
sagengcc $(CFLAGS) $(INCLUDES) test2.c libo-client.a -o test2 -lstdc++
. Die bessere option ist-so der Vorschlag von Jonathan Leffler verwendeng++
stattgcc
Schreiben Sachen in C++ verwendet werden können C ohne jegliche Zusätze C++ erfordert, ist sehr schwer. Wahrscheinlich sogar noch compiler-abhängig. Ihre Bibliothek benötigt die C++ runtime, und die zum initialisieren der C++ runtime presumaby erfordert Besondere Unterstützung vor caling main() in Ihrem Programm. Ihre chimaera in noch einem C++ - Programm wenn Sie den link in C-Dateien, auch wenn es in main() und alles andere außerhalb Ihrer Bibliothek.