Mischen von libstdc ++ -Versionen

8

Es gibt zwei Software-Teams, die C ++ - Anwendungen für das gleiche Betriebssystem entwickeln (Scientific Linux 6.5):

Team_A verwendet den vom Betriebssystem bereitgestellten Compiler und die Bibliotheken (GCC 4.4.7, GLIBC_2.12, GLIBCXX_3.4.13), um seine C ++ 98-Anwendung und verschiedene gemeinsame Bibliotheken zu erstellen.

Team_B verwendet eine neuere GCC-Version (4.8.3), die aus der Quelle erstellt wurde. Es ist ein nativer Compiler, es verbindet sich mit der OS-libc und verwendet die OS-Standard-Header, hat aber eine eigene Version von stdc ++ (GLIBCXX_3.4.19). Team_B verwendet diesen Compiler im C ++ 11-Modus, um seine Anwendung zu erstellen ( AppB ), und implementiert dabei libstdc ++ und libgcc_s.

Team_A stellt Services für Team_B in Form einer gemeinsam genutzten Bibliothek (.so, .hpp) bereit: LibA . Die API der Bibliothek besteht aus einer Reihe von C ++ - Klassen (Deklaration im Header, Implementierung in .so), und die Methoden verwenden std :: string und andere stdc ++ - Klassen als Argumente.

An diesem Punkt kommen wir zu dem Problem: AppB konstruiert GLIBCXX_3.4.19 C ++ 11 Stil std :: whatever Objekte und übergibt sie an LibA wer interpretiert sie als GLIBCXX_3.4.13 C ++ 98 Stil Objekte, und dies möglicherweise nicht vorwärtskompatibel sein.

Ist das ein Problem? Kann es zu einem Anwendungsabsturz kommen? Sind die std :: whatever Implementierungen zwischen den Versionen kompatibel (selbes Speicherlayout)? Was ist mit C ++ 98 vs C ++ 11?

Einige Handlungswechsel, die mich verwirrter machen:

  • AFAICT, wenn AppB läuft, ist nur ein libstdc ++ geladen, der neuere ein. Selbst wenn LibA mit dem älteren verlinkt, wird es nicht geladen.
  • Aber Symbole in libstdc ++ sind versioniert. Also, wenn LibA explizit ein verwendet ältere Version eines Symbols wird dagegen verlinkt. Das heisst In AppB werden 2 verschiedene Implementierungen derselben Funktion verwendet und LibA.
  • std :: string und container sind Template-Klassen, das heißt ein Teil ihrer Implementierung endet dort, wo sie generiert wird, ein Teil davon in libstdc ++. Auch wenn das neuere libstdc ++ geladen ist, wird das generiert Vorlagencode in LibA stammt aus der älteren Version.

Ich würde gerne verstehen, was genau in diesem Fall passiert, wenn es riskant ist und Probleme aufheben. Es ist keine Option, die Teams in die gleiche Entwicklungsumgebung zu bringen. Das Entfernen von std :: classes aus der API wäre ebenfalls sehr schwierig.

Irgendwelche Hinweise willkommen! :)

    
Gyorgy Szekely 10.01.2015, 20:43
quelle

1 Antwort

3

Im Gegensatz zu C gibt es keinen definierten ABI für C ++. Das heißt ....

  1. Das C ++ Mangling kann sich ändern wikipedia: name mangling . Beachten Sie, wie sich die Namensänderung von Alpha geändert hat.
  2. Die Struktur einer Klasse kann unterschiedlich sein. Es kann verschiedene Entscheidungen geben, wie protected: , private: und public: Teile der Struktur angeordnet werden. Die Position und Bedeutung der V-Tabelle kann zwischen Compilern verschoben werden. Es kann verschiedene vordefinierte Funktionen wie die typeinfo in der vtable zwischen den verschiedenen Compiler-Versionen geben.
  3. Die Implementierung einer Struktur in der STL kann zwischen den Versionen von C ++ unterschiedlich sein (z. B. wurde die Zeichenfreigabe in früheren Visual Studio-Implementierungen durchgeführt, wurde aber in C ++ 11 verboten).
  4. In Windows können verschiedene Laufzeiten ihren Speicher anders verwalten (binden Sie an verschiedene malloc / free). Wenn Sie vollständige Objekte oder Zeiger übergeben, kann dies dazu führen, dass die falsche freie Implementierung aufgerufen wird.

Was können Sie tun, um diese Probleme zu beheben?

Quellenfreigabe

Anstatt eine kompilierte Bibliothek bereitzustellen, müssen Sie die Dienste als Quellcode bereitstellen, der in derselben Umgebung kompiliert wird.

Standardisieren Sie libstdc ++

Der Source-Compiler kann mit dem älteren stdC ++ neu erstellt werden. Dies würde die Auswirkungen von Punkt 3) begrenzen.

Erstellen Sie eine Fassade

Es gibt eine Schnittstelle zwischen den beiden Teams, die eine gemeinsame Sprache sprechen müssen. Diese Sprache sollte wahrscheinlich C sein.

Team A = & gt; C ++ Fassade / Stub = & gt; C Schnittstelle = & gt; C ++ Fassade / Proxy = & gt; Team B.

Die Fassade sollte in der Umgebung gebaut werden, in der sie verwendet wird.

    
mksteve 31.08.2015, 11:26
quelle

Tags und Links