Вопрос по undefined-reference, c++, g++, name-mangling – Это не так. Они не являются частью C, но C ++.

33

ел несколько похожих вопросов (например,этот, тот или жеэтот), но никто из них не помог мне решить мою проблему. У меня есть файл * .so (из ядраГНСС-СПЗ) что, как указано:

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

содержит символGps_Ephemeris::Gps_Ephemeris(), который должен быть конструктором.

Я написал минимальный код:

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

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

который я собираю с:

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

Затем компоновщик жалуется:

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

Я тоже пробовалCMake, но сгенерированная строка была похожа на эту (просто добавила-rdynamic перед связыванием), и он по-прежнему генерировал точно такую ​​же ошибку компоновщика.

Обратите внимание, что и библиотека, и мой минимальный код компилируются с помощью одного и того же компилятора (g ++ - 5), с точно такими же флагами и тем же стандартом c ++ 0x.

Обращаясь к ответу Максима Егорушкина, строчка:

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

ничего не выводит. Однако символ определен в статической библиотеке (то есть * .a библиотека):

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

Зная, что обаCMake, следующим образом:

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

не должно быть никакой разницы в символах, содержащихся / определенных в этих библиотеках, верно? Я ничего не заметил вCMakeдокументация наadd_library, Я что-то упускаю из виду?

Спасибо, что заметили, я исправил это. Я в основном занимаюсь компьютерным зрением на высоком уровне, так что да, я чувствую себя неквалифицированным, чтобы судить, что должно быть исключено. Я опубликую вывод, как только смогу. Ash
Вы сказали, что выходсодержит символGps_Ephemeris::Gps_Ephermeris(), но не показывает фактический результат. Это актуально и будет полезно. Кроме того, вы явно не скопировали и не вставили этот символ в вопрос, потому что вы его неправильно написали. Я не доверяю письменным резюме такого рода, потому что, если бы вы были надежным судьей того, что исключать из своего резюме, вы, вероятно, не задавали бы вопрос. Useless
Не глядя на исходный код, трудно сказать, почему .so и .a, построенные из одних и тех же источников, экспортируют разные символы. Условная компиляция может быть вовлечена. Maxim Egorushkin
Каковы искаженные имена символов как в main.o, так и в libgnss_system_parameters_dyn.so? G ++ изменял название искажения иногда, когда менялся ABI. Возможно, libgnss_system_parameters_dyn.so была скомпилирована не так, как вы компилируете main.cpp. Пытатьсяg++ -std=c++0x -c main.cpp; nm main.o и сравните искаженные имена с тем, что в библиотеке. Waxrat

Ваш Ответ

2   ответа
21

.so экспортирует символnm --demangle --dynamic --defined-only --extern-only <lib.so> | grep <symbol>.

Без--defined-only ваша команда также показываетне определено символы.

Без--extern-only он также показывает символы свнутренняя связь которые недоступны для ссылок.

Похоже, вам нужно связать другую библиотеку, потому чтоGps_Ephemeris::Gps_Ephermeris() не разрешается путем ссылкиlibgnss_system_parameters_dyn.so, Хороший способ начать - это документация и примеры этой библиотеки.

Большое спасибо! Ты был прав. Однако символы присутствуют в (эквивалентной) статической библиотеке. Я обновил вопрос с некоторой информацией в конце. Не могли бы вы взглянуть? Ash
1

что этот тип ошибки вызван отсутствием надлежащегоextern "C" { ... } брекетинг во включаемом файле.

Это не так. Они не являются частью C, но C ++. Nicole
Не могли бы вы уточнить, какextern "C" связь обрабатывает конструкторы? Maxim Egorushkin

Похожие вопросы