2017-04-06 6 views
32

Ich fand eine Reihe von ähnlichen Fragen (z. B. this, that oder this), aber keiner von ihnen half mir mein Problem zu lösen. Ich habe eine * .so Datei (aus dem Kern gnss-sdr), dass, wie angegeben:g ++ undefined Referenz obwohl Symbol in * .so Datei

$nm libgnss_system_parameters_dyn.so | c++filt |grep Gps_Eph 

enthält das Symbol Gps_Ephemeris::Gps_Ephemeris(), das angeblich ein Konstruktor sein.

Ich habe einigen minimalen Code geschrieben:

#include <iostream> 
#include <core/system_parameters/gps_ephemeris.h> 

int main(int argc,const char* argv[]) 
{ 
    Gps_Ephemeris ge; 
    return 0; 
} 

, die ich mit kompilieren:

g++ main.cpp -std=c++0x -I some_include_path -L some_lib_path -l gnss_system_parameters_dyn` 

Der Linker dann klagt:

/tmp/ccHCvldG.o: In function `main': 
main.cpp:(.text+0x33): undefined reference to `Gps_Ephemeris::Gps_Ephemeris()' 
collect2: error: ld returned 1 exit status 

Ich habe auch versucht Cmake, aber die Linie, die es erzeugte, war dem ähnlich (es fügte geradehinzuvor dem Verknüpfen), und es erzeugte immer noch genau den gleichen Linker-Fehler.

Beachten Sie, dass sowohl die Bibliothek als auch mein minimaler Code mit demselben Compiler (g ++ - 5) kompiliert werden, mit genau denselben Flags und dem gleichen C++ 0x-Standard.


Adressierung der Antwort von Maxim Egorushkin, die Zeile:

nm --demangle --defined-only --extern-only libgnss_system_parameters.so |grep Gps_Eph 

nichts ausgibt. Jedoch wird das Symbol in der statischen Bibliothek (dh die * .a Bibliothek) definiert:

00000000000006b0 T Gps_Ephemeris::Gps_Ephemeris() 
00000000000006b0 T Gps_Ephemeris::Gps_Ephemeris() 

Wissen, dass beide von Cmake, in der folgenden Weise erzeugt werden:

add_library(lib_name SHARED ${sources_etc}) #for the *.so 
add_library(lib_name_2 ${sources_etc}) #for the *.a 

Es sollte keinen Unterschied in den Symbolen geben, die in diesen Bibliotheken enthalten sind, oder? Ich habe nichts in cmake 's Dokumentation auf add_library bemerkt. Fehle ich etwas Offensichtliches?

+3

Sie sagten, die Ausgabe _enthalte das Symbol 'Gps_Ephemeris :: Gps_Ephisheris()' _, zeige aber nicht die tatsächliche Ausgabe an. Dies ist relevant und wäre nützlich. Außerdem haben Sie dieses Symbol offensichtlich nicht in die Frage kopiert und eingefügt, weil Sie es falsch geschrieben haben. Ich bin solchen schriftlichen Zusammenfassungen gegenüber misstrauisch, denn wenn Sie ein zuverlässiger Richter wären, was Sie von Ihrer Zusammenfassung ausschließen könnten, würden Sie diese Frage wahrscheinlich nicht stellen. – Useless

+0

Danke, dass ich es bemerkt habe. Ich mache meistens Computer Vision auf hohem Niveau, also fühle ich mich unqualifiziert zu beurteilen, was ausgeschlossen werden muss. Ich werde die Ausgabe so bald wie möglich veröffentlichen. – Ash

+0

Ohne den Quellcode zu betrachten, ist es schwer zu sagen, warum die .so und .a, die aus den gleichen Quellen stammen, verschiedene Symbole exportieren. Bedingte Kompilierung kann beteiligt sein. –

Antwort

17

Der pedantisch korrekte Weg, um zu überprüfen, ob ein .so ein Symbol exportiert, ist nm --demangle --dynamic --defined-only --extern-only <lib.so> | grep <symbol>.

Ohne --defined-only zeigt Ihr Befehl auch undefined Symbole.

Ohne --extern-only zeigt es auch Symbole mit interne Verknüpfung, die für die Verknüpfung nicht verfügbar sind.

Offenbar müssen Sie eine andere Bibliothek verknüpfen, da Gps_Ephemeris::Gps_Ephermeris() nicht durch Verknüpfung von libgnss_system_parameters_dyn.so aufgelöst wird. Ein guter Anfang sind die Dokumentation und Beispiele dieser Bibliothek.

+0

Vielen Dank! Du hattest Recht. Die Symbole sind jedoch in der (äquivalenten) statischen Bibliothek vorhanden. Ich habe die Frage am Ende mit einigen Informationen aktualisiert. Könnten Sie bitte einen Blick darauf werfen? – Ash

1

Ich habe in der Vergangenheit festgestellt, dass diese Art von Fehler durch das Fehlen von extern "C" { ... } Belichtungsreihen in einer Include-Datei verursacht wird.

+1

Könnten Sie erläutern, wie "extern" C "" Verknüpfungen Konstruktoren behandelt? –

+0

Es tut es nicht. Sie sind nicht Teil von C, sondern von C++. – Nicole