虽然符号出现在*.so文件中,但是g ++未定义引用

Ash*_*Ash 36 c++ g++ name-mangling undefined-reference

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

$nm libgnss_system_parameters_dyn.so  | c++filt  |grep Gps_Eph
Run Code Online (Sandbox Code Playgroud)

包含符号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; 
}
Run Code Online (Sandbox Code Playgroud)

我编译的是:

g++  main.cpp -std=c++0x -I some_include_path -L some_lib_path -l gnss_system_parameters_dyn`
Run Code Online (Sandbox Code Playgroud)

然后链接器抱怨:

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

我也尝试过cmake,但它生成的行类似于它(它只是-rdynamic在链接之前添加),它仍然生成完全相同的链接器错误.

请注意,库和我的最小代码都使用相同的编译器(g ++ - 5)进行编译,具有完全相同的标志和相同的c ++ 0x标准.


解决Maxim Egorushkin的答案:

nm --demangle --defined-only --extern-only libgnss_system_parameters.so  |grep Gps_Eph
Run Code Online (Sandbox Code Playgroud)

不输出任何东西.但是,符号在静态库中定义(*.a库):

00000000000006b0 T Gps_Ephemeris::Gps_Ephemeris()
00000000000006b0 T Gps_Ephemeris::Gps_Ephemeris()
Run Code Online (Sandbox Code Playgroud)

知道两者都是由cmake生成的,方式如下:

add_library(lib_name SHARED ${sources_etc}) #for the *.so
add_library(lib_name_2 ${sources_etc}) #for the *.a
Run Code Online (Sandbox Code Playgroud)

这些库中包含/定义的符号应该没有区别,对吧?我在cmake的文档中没有注意到任何内容add_library.我错过了一些明显的东西吗

Max*_*kin 25

检查.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.一个好的开始方式是库的文档和示例.


Nic*_*ole 6

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