2017-12-16 6 views
2

Angenommen, eine Anwendung myapp.exe wird mit g++ erstellt und verwendet das Flag -static-libstdc++, so dass es in Umgebungen ohne libstdc++.so installiert werden kann. myapp.exe fügt auch Plugin-Unterstützung für eine Funktion plugf hinzu, die über eine Shard-Bibliothek dynamisch über dlopen geladen werden kann.Wie unterstützt man dynamische Plugins beim statischen Verknüpfen in Standardbibliotheken?

Wenn libplug.so ist eine solche Plugin-Bibliothek, die auch auf libstdc++ verweist, wie kann es so in der Lage sein, mit myapp.exe arbeiten?

Dies ist einfach, wenn libstdc++ sowohl in dynamisch verbunden ist, da myapp.exe und libplug.so die gleiche dynamisch geladene Standardbibliothek verwenden, aber es ist mir nicht klar, wie dies am besten verknüpft Standardbibliotheken mit statisch zu tun.

Ein Ansatz, den ich überlege mir ist libplug.so auch die Flagge -static-libstdc++ verwenden zu haben und verwenden Sie dann die version script

{ 
    global: plugf; 
    local: *; 
}; 

um sicherzustellen, dass seine Version der Standard-Bibliothek verwendet wird, aber das würde bedeuten, dass es sein würde, zwei Kopien von libstdc++ in den Speicher geladen. Ich weiß, dass dieser Ansatz nicht vom C++ - Standard gesegnet würde, da er ORD-Verletzungen hätte, aber ist es etwas, das libstdc++ in irgendeiner Weise unterstützt? Der Abschnitt Multiple ABI testing des Abschnitts manual verweist auf ein Szenario, das ähnlich klingt.

+1

Leider müssen Sie eine dynamisch/statisch verknüpfte libstdC++ an "libplug.so" anpassen - und ja, zwei Kopien würden zur Laufzeit geladen werden. Und ja, Sie könnten in Schwierigkeiten geraten, wenn Ihr Plugin einen Zeiger mit einer Version von libstdC++ zurückgibt und Sie es mit einer anderen Version freigeben. – Mikhail

+0

Ich glaube nicht, dass das stimmt. Die Zuweisung wird von der Standard-c-Bibliothek gehandhabt, und '-static-libstdC++' bewirkt nicht, dass 'libc' statisch verknüpft wird, so dass sie beide das gleiche' libc.so' verwenden. – rnickb

+0

Ich denke, Objekte werden mit '__gnu_cxx :: new_allocator' in libstdC++ zugewiesen, vielleicht, da Sie darauf hinweisen, dass sie beide zum selben' libc.so' gehen. Aus persönlicher Erfahrung hatte ich das oben erwähnte Problem mit MSVC RT. – Mikhail

Antwort

1

Ja, würde diese Lösung arbeiten, aber

  • es stellt bestimmte Overhead durch Code-Duplizierung
  • es brechen kann, wenn Sie versuchen, STL Objekte zwischen Plugin/app passieren aufgrund ABI changes in recent libstdc++

Das Löschen von Objekten, die von std::allocator in verschiedenen C++ - Laufzeit zugewiesen wurden, sollte unter Linux funktionieren, obwohl ich in libstdC++ - Dokumenten keine explizite Anweisung dazu finden konnte. Unter Windows schlägt es fehl, wie Mikhail in Kommentaren hervorgehoben hat.

+0

Die ABI-Änderungen sind nur zwischen den C++ 98 und C++ 11 Versionen von libstdC++, richtig? – rnickb

+1

@rnickb Nein, Sie erhalten neue ABI in allen post-GCC5 libstdC++ unabhängig von der '-std'-Flagge (siehe [diese Seite] (https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html)) für mehr Details). Es macht Sinn, weil 'std :: string' in Code, der mit' -std = C++ 98' und '-std = C++ 11' kompiliert wurde, besser binär kompatibel sein sollte. – yugr

Verwandte Themen