36 votes

g ++ référence non définie bien que le symbole soit présent dans le fichier * .so

J'ai trouvé un certain nombre de questions similaires (par exemple, cet, cette ou ce), mais aucun d'entre eux m'a aidé à résoudre mon problème. J'ai un *.si le fichier (à partir de la base de gnss-sdr) que, comme indiqué par:

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

contient le symbole Gps_Ephemeris::Gps_Ephemeris(), ce qui est censé être un constructeur.

J'ai écrit un minimum de code:

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

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

qui je compile avec:

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

L'éditeur de liens puis se plaint:

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

J'ai aussi essayé de cmake, mais la ligne a été généré similaires (il a juste ajouté -rdynamic avant de liaison), et il a encore généré exactement la même erreur d'éditeur de liens.

Il est à noter que la bibliothèque et mon code minimal sont compilés avec le même compilateur g++-5), avec exactement les mêmes drapeaux et la même c++0x standard.


L'adressage de la réponse par la Maxime Egorushkin, la ligne:

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

ne pas afficher quoi que ce soit. Toutefois, le symbole est défini dans la bibliothèque statique (c'est à dire de la *.une bibliothèque):

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

Sachant que les deux sont générés par cmake, de la manière suivante:

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

il devrait y avoir aucune différence dans les symboles figurant définies dans les bibliothèques, droit? Je n'ai pas remarqué quoi que ce soit dans cmakela documentation sur add_library. Ai-je raté quelque chose d'évident?

25voto

Maxim Yegorushkin Points 29380

La manière affectée de façon correcte à vérifier qu'un .so des exportations d'un symbole est - nm --demangle --dynamic --defined-only --extern-only <lib.so> | grep <symbol>.

Sans --defined-only de votre commande indique également undefined symboles.

Sans --extern-only il montre aussi les symboles avec une liaison interne qui ne sont pas disponibles pour la liaison.

Il semble que vous avez besoin de faire un lien d'une autre bibliothèque, car Gps_Ephemeris::Gps_Ephermeris() n'est pas résolu en reliant libgnss_system_parameters_dyn.so. Une bonne façon de commencer est que de la bibliothèque de la documentation et des exemples.

2voto

Nicole Points 374

J'ai constaté par le passé que ce type d'erreur était dû à un manque de bracketing correct extern "C" { ... } dans un fichier à inclure.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X