2009-06-03 9 views
2

Ich habe eine Verknüpfung Problem. Ich muss eine Verbindung zu einer gemeinsamen Bibliothek libfoo.so herstellen, die von einer Funktion read abhängt, die ich selbst in der Datei read.c. definieren möchtenm Berichte Symbol ist definiert, aber LDD Berichte Symbol ist undefined

ich kompilieren und verknüpfen alles zusammen, aber zur Laufzeit erhalte ich die Fehler

/home/bar/src/libfoo.so: undefined symbol: sread. 

nm das Symbol Berichte definiert ist

$nm baz | grep sread 
    00000000000022f8 t sread 

aber LDD meldet das Symbol

$ldd -r baz | grep sread 
undefined symbol: sread (/home/bar/src/libfoo.so) 
nicht definiert ist

Was gibt? Gibt es einen Grund dafür, dass libfoo.so eine gemeinsame Bibliothek ist?

+0

Vielleicht sollten Sie die vollständigen Verbindungslinien für alle Ihre gemeinsamen Objekte und ausführbaren Dateien veröffentlichen, um das Thema zu beleuchten. – lothar

Antwort

13

Erstens ist die Definition einer Funktion namens 'read' eine schlechte Idee (TM), da es sich um eine Standard-libc-Funktion auf allen UNIXen handelt. Das Verhalten Ihres Programms ist nicht definiert, wenn Sie dies tun.

Zweitens ist die read Funktion, die Sie in libbaz.so definiert haben, mit einem 't' in nm Ausgang markiert. Dies bedeutet, dass diese Funktion lokal ist (außerhalb von libbaz.so nicht sichtbar). Globale Funktionen sind mit 'T' durch nm gekennzeichnet.

Haben Sie 'static int read(...)' verwendet, als Sie es in read.c definiert haben? Wenn nicht, haben Sie ein Linker-Skript oder attribute((visibility(hidden))) oder vielleicht -fvisibility=hidden auf der Befehlszeile verwendet, wenn Sie libbaz.so kompiliert und verknüpft haben?

+0

Der Name der Funktion wird nicht wirklich gelesen, ich habe nur versucht, die Dinge einfach zu machen. Ahh ... Sie sind richtig, ich verwende -Wl, - Version-Skript, das eine Datei enthält, die alle Symbole lokal außer zwei enthält, die ich exportieren möchte. Ich muss natürlich auch die Lesefunktion exportieren. – codehippo

-1

Wenn Sie Ihre gemeinsam genutzte Bibliothek erstellen, müssen Sie alle undefined Symbole entweder innerhalb derselben Bibliothek oder einer anderen (gemeinsam genutzten) Bibliothek auflösen. Der Linker wird nicht ein nicht definiertes Symbol aus einer Bibliothek mit einem Symbol aus Ihrer Anwendung auflösen.

+0

Ich sollte klarstellen, dass Baz tatsächlich eine gemeinsame Bibliothek ist. Bedeutet das also, dass ich eine gemeinsam genutzte Bibliothek erstellen sollte, die nur die Lesefunktion enthält, und eine Verbindung dazu herstellen? Gibt es eine explizite Möglichkeit, dem Linker zu sagen, dass er die nicht definierten Symbole aus der gemeinsam genutzten Bibliothek libfoo.so mit dieser anderen gemeinsam genutzten Bibliothek (zB libread.so) auflösen soll? – codehippo

+2

Sie irren sich: Der Runtime Loader löst glücklicherweise ein undefiniertes Symbol aus einer gemeinsam genutzten Bibliothek mit einem Symbol aus der Hauptdatei, vorausgesetzt das Symbol wird in seiner dynamischen Tabelle "exportiert" (was zB passiert, wenn die ausführbare Datei mit -rdynamic verknüpft ist) . –

+0

@codehippo Sie haben nicht gesagt, dass Baz eine gemeinsame Bibliothek war und der Name führt auch nicht zu dieser Annahme. – lothar

1

Der obige Fehler kann auch auftreten, wenn C-Code mit G ++ kompiliert und dann verknüpft wird. G ++ führt Namensfehlern aus, so dass das tatsächliche Symbol etwas wie "_Zsds_ [Funktionsname] _" sein kann, was den Linker zum Würgen bringt, wenn er nach dem nicht entstellten Namen sucht.

Ich lief heute das gleiche Verhalten, außer dass mein Problem nach den unter Wikipedia beschriebenen Aktionen gelöst wurde. Im Grunde wird C-Code, der mit einem C++ - Compiler kompiliert wird, in der Symboltabelle einen "gemangelten" Namen haben, der dazu führt, dass die C-Stil-Symbolauflösung fehlschlägt.