Ich arbeite an einem C ++ - Projekt, das zwei Bibliotheken von Drittanbietern benötigt ( libfoo.so und libbar.so ). Mein Betriebssystem ist Linux.
libfoo.so ist dynamisch mit libpng14.so.14 (1.4.8) (EDIT 1)
verknüpft libbar.so scheint statisch mit einer unbekannten Version von libpng libpng 1.2.8 (EDIT 1)
Ich sage "scheint zu sein", weil:
ldd libbar.so
zeigt nichts über png nm -D libbar.so | grep png_read_png
sagt "004f41b0 T png_read_png" less libbar.so | grep png_read_png
sagt "4577: 004f41b0 738 FUNC GLOBAL DEFAULT 10 png_read_png" Wenn ich mein Programm starte, bricht es ab:
%Vor%Dies ist gdb backtrace:
%Vor%Wie Sie sehen, wird eine Ausnahme in Foo :: Image :: load geworfen, die zu libfoo.so
gehörtWenn ich den Teil meines Codes deaktiviere, der libbar.so verwendet und das Verknüpfen mit ihm löscht, löst Foo :: Image :: load keine Ausnahme aus und funktioniert einwandfrei .
BEARBEITEN 1
png_access_version_number ()
png_access_version_number()
return 10208
: Version 1.2.8 png_access_version_number()
return 10408
: Version 1.4.8 Da Sie keine der Bibliotheken neu erstellen können, und da die Bibliotheken aufgrund von in Konflikt stehenden Symbolen nicht im selben "Dynamic Linker Namespace" residieren können, besteht die einzige Möglichkeit darin, isolieren sie.
Sie können dies erreichen, indem Sie dlopen("lib*.so", RTLD_LOCAL)
(für eine oder beide Bibliotheken) verwenden, anstatt direkt mit ihnen zu verknüpfen.
Dies könnte praktikabel sein, wenn Sie nur ein paar Symbole aus z. libfoo.so
- Sie können einfach dlsym
verwenden, anstatt die Funktionen direkt aufzurufen.
Wenn Sie zu viele Abhängigkeiten von beiden Bibliotheken haben, könnte Ihre andere Lösung darin bestehen, eine "Interposer" -Bibliothek zu erstellen. Nehmen wir an, Sie möchten libbar.so
einfügen und Sie benötigen bar1()
, bar2()
, ... bar1000()
.
Schreiben Sie (oder erzeugen Sie mit einem einfachen Perl-Skript) eine Quelldatei, die wie folgt aussieht:
%Vor% Kompilieren und verlinken Sie diese Quelle jetzt in libbar_interposer.so
und verknüpfen Sie Ihre Anwendung damit (dies funktioniert nicht für C++
wegen Namensmangel, nur für plain- C
). Voila, keine Quelle ändert sich in der Anwendung, und Sie haben noch libbar.so
isoliert, so dass ihre Symbole für den Rest der Anwendung nicht sichtbar sind, und insbesondere keinen Konflikt mit Symbolen in libpng
.
Tags und Links c++ linker shared-libraries symbols libpng