g++ 未定义的引用,尽管符号存在于 *.so 文件中

g++ undefined reference although symbol is present in *.so file

本文关键字:存在 so 文件 符号 未定义 引用 g++      更新时间:2023-10-16

我发现了许多类似的问题(例如这个,那个或这个),但没有一个帮助我解决问题。我有一个 *.so 文件(来自 gnss-sdr 的核心),如下所示:

$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 标准编译的。


针对马克西姆·埃戈鲁什金(Maxim Egorushkin)的答案,这句话:

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的文档中的任何内容。我错过了一些明显的东西吗?

检查.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来解决。一个好的开始方法是该库的文档和示例。

我过去发现这种类型的错误是由于包含文件中缺少适当的extern "C" { ... }括号引起的。