g++ 未定义的引用,尽管符号存在于 *.so 文件中
g++ undefined reference although symbol is present in *.so file
我发现了许多类似的问题(例如这个,那个或这个),但没有一个帮助我解决问题。我有一个 *.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" { ... }
括号引起的。
- C++模板来检查友元函数的存在
- 如何使用ndk-build.cmd构建Android.so文件
- 既然存在危险,为什么项目要使用-I include开关
- 我们可以访问一个不存在的联盟的成员吗
- C++:对不存在的命名空间使用命名空间指令
- C++quit()函数中可能存在作用域问题
- C++擦除(如果存在)
- g++ 说函数不存在,即使包含正确的标头
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 在C++代码中包含opencv时,使用ctypes创建.so文件
- 有了gcc,是否可以链接库,但前提是它存在
- C++LinkedList问题.数据类型之间存在冲突?没有匹配的构造函数
- gcc和clang在表达式是否为常量求值的问题上存在分歧
- C++Builder中的OnClick事件签名存在问题
- 如何正确地将分支添加到已存在的树中
- 由于相同的文件名/类名存在于不同的SO中而导致的SEG错误
- g++ 未定义的引用,尽管符号存在于 *.so 文件中
- .so中存在的符号已编译.o引用了它,但链接失败
- getPlatformIDs() 返回 -1001,即使 nvidia.icd 存在并包含'libcuda.so'
- [UnixODBC][驱动程序管理器]无法打开 lib '/usr/lib/libmyodbc.so' :找不到文件,但文件存在