[linux] shared obj: falsche Funktion wird gerufen

Hi,

so ganz hab ich das alles nicht verstanden, daher leider nur eine vage Beschreibung. Bei Unklarheiten bitte nachfragen.

Ich habe einen Batzen C-Quellen, die kompiliere und linke (mit

# gcc -shared -fPIC -o libfoo.so \*.o

) ich zu einem shared object. In diesen Quellen gibt es eine Funktion foobar().

Weiterhin habe ich ein anderes shared object libbar.so, das ebenfalls eine gleichartige Funktion foobar() enthaelt. Beide Bibliotheken werden jetzt von einem Programm geladen, welches eine Funktion Init() aus libfoo.so aufruft. Das Problem ist jetzt, dass Init() foobar() ruft, und zwar das falsche aus libbar.so.

Wie kann ich das verhindern? Kann ich beim linken irgendwie sagen, dass er Referenzen auf Funktionen nur innerhalb des objects aufloesen soll? Das Umbenennen der Funktion in einer der beiden objects ist leider keine Option, da die Quellen von libfoo.so ueberwiegend automatisch von dem Programm einschliesslich libbar.so generiert werden (letzten Endes ist das foobar() aus libfoo.so das generierte Gegenstueck von foobar() aus libbar.so).

Hoffe, ich konnte mich verstaendlich ausdruecken. Danke im Vorraus fuer jede Hilfe,
Gruss vom Frank.

Hi,

so ganz hab ich das alles nicht verstanden, daher leider nur
eine vage Beschreibung. Bei Unklarheiten bitte nachfragen.

Ich habe einen Batzen C-Quellen, die kompiliere und linke (mit

gcc -shared -fPIC -o libfoo.so *.o

) ich zu einem
shared object. In diesen Quellen gibt es eine Funktion
foobar().

Weiterhin habe ich ein anderes shared object libbar.so, das
ebenfalls eine gleichartige Funktion foobar() enthaelt. Beide
Bibliotheken werden jetzt von einem Programm geladen, welches
eine Funktion Init() aus libfoo.so aufruft. Das Problem ist
jetzt, dass Init() foobar() ruft, und zwar das falsche aus
libbar.so.

Wie kann ich das verhindern? Kann ich beim linken irgendwie
sagen, dass er Referenzen auf Funktionen nur innerhalb des
objects aufloesen soll? Das Umbenennen der Funktion in einer
der beiden objects ist leider keine Option, da die Quellen von
libfoo.so ueberwiegend automatisch von dem Programm
einschliesslich libbar.so generiert werden (letzten Endes ist
das foobar() aus libfoo.so das generierte Gegenstueck von
foobar() aus libbar.so).

Unter Unix/Linux werden sogenannte one-pass Linker verwendet, diese arbeiten in nur einem Durchlauf. Die Auflösung der Symbole erfolgt dabei von in der Reihenfolge, in welcher du die Objekt/libs/so angegegebn hast. Rufst du in einer main() die Funktion foo() auf und linkst lib1.a und lib2.so (beide enthalten dieses Symbol), so wird die Funktion im ersten Vorkommen (lib1.a) ersetzt. Weitere Vorkommen in späteren Bibliotheken (lib2.so) werden ignoriert.
Wäre deine Linkreihenfolge modul_1 => lib1.a => modul_2 => lib2.so, so würde aus Modul_1 eine andere Funktion auf[Edit: Firmenname entfernt]fen, als aus Modul 2.

Im begrenzten Rahmen hast du somit eine Möglichkeit durch die Linkreihenfolge Einfluß zu nehmen. Bei mehreren Symbolen mit cross-references wird das beliebig unübersichtlich.
Alternativ kannst du dir natürlich einen Wrapper für jede der Funktionen schreiben, die Linkreihenfolge ist dann … wrapper.o libfoo.so … (hier verwendest du natürlich andere Symbolnamen)

Der Wortfuchs