C++纯虚基类和类的静态成员未定义引起的链接问题

C++中基类如果是纯虚类,并且析构函数做了声明但未定义的话,编译可以过,链接时会导致报错说该类未定义。类有static变量成员时,如果未定义,链接会报错这个变量未定义。这些语法细节不记得的话,遇到错误时只看表面的错误信息,一下想不起来为什么报错有点浪费时间,做下记录。

例如:

E0103 22:47:55.505376 42954 class_loader_utility.cc:218] mainboardLibraryLoadException: /apollo/bazel-bin/modules/perception/image_stitch/../../../_solib_local/_U_S_Smodules_Sperception_Simage_Ustitch_Cimagestitch_Udceplus___Umodules_Sperception_Simage_Ustitch_Sbuild_Ux86/libdcepluscuda.so: undefined symbol: _ZTIN6apollo10perception6camera11imagestitch3pre13NormalizationE library_path:/apollo/bazel-bin/modules/perception/image_stitch/libimage_stitch_component.so

E0103 22:47:55.505409 42954 class_loader_utility.cc:234] mainboardshared library failed: /apollo/bazel-bin/modules/perception/image_stitch/libimage_stitch_component.so

E0103 22:47:55.505439 42954 class_loader_manager.h:78] mainboardInvalid class name: ImageStitchComponent

E0103 22:47:55.505457 42954 module_controller.cc:69] mainboardFailed to load module: modules/perception/image_stitch/dag/image_stitch.dag

E0103 22:47:55.505462 42954 class_loader_utility.cc:256] mainboardAttempt to UnloadLibrary lib, but can't find lib: /apollo/bazel-bin/modules/perception/image_stitch/libimage_stitch_component.so

E0103 22:47:55.505466 42954 mainboard.cc:39] mainboardmodule start error.

执行命令

nm -D /apollo/bazel-bin/modules/perception/image_stitch/../../../_solib_local/_U_S_Smodules_Sperception_Simage_Ustitch_Cimagestitch_Udceplus___Umodules_Sperception_Simage_Ustitch_Sbuild_Ux86/libdceplusnorm.so |grep "_ZTIN6apollo10perception6camera11imagestitch3pre13NormalizationE"

得到结果

U _ZTIN6apollo10perception6camera11imagestitch3pre13NormalizationE

输出显示 U(Undefined),说明这个符号在 libdceplusnorm.so 中是被引用的,而不是被定义的。执行下面的命令查看typeinfo:

c++filt _ZTIN6apollo10perception6camera11imagestitch3pre13NormalizationE

输出 typeinfo for apollo::perception::camera::imagestitch::pre::Normalization

那可能的原因是:包含Normalization类定义的源文件没有被编译进任何库或类是纯虚类,但缺少至少一个虚函数的实现,或者链接时缺少包含该类实现的库。这里属于第一种情况,Normalization类是纯虚基类,要确保至少析构函数在 .cpp 文件中有实现定义,哪怕是空的:

normalization.hpp

class Normalization {

public:

virtual ~Normalization();

// ...

};

需要在normalization.cpp里增加下面这句才不会报链接错误,因为子类析构时需要调用到基类的析构函数,基类的析构函数需要有实现:

Normalization::~Normalization() = default;

或者把normalization.hpp里的virtual ~Normalization(); 删掉也不会报链接报错,但这个不规范,相当于让编译器去隐式实现,编译器的实现做得不好可能会在运行时出现莫名其妙的崩溃问题。

加了定义后再执行命令

nm -D /apollo/bazel-bin/modules/perception/image_stitch/../../../_solib_local/_U_S_Smodules_Sperception_Simage_Ustitch_Cimagestitch_Udceplus___Umodules_Sperception_Simage_Ustitch_Sbuild_Ux86/libdceplusnorm.so |grep "_ZTIN6apollo10perception6camera11imagestitch3pre13NormalizationE"

可以看到库文件里的符号有对应地址了:

00000000002a3fb8 V _ZTIN6apollo10perception6camera11imagestitch3pre13NormalizationE

E0124 18:43:53.675529 6208 class_loader_utility.cc:218] mainboardLibraryLoadException: /apollo/bazel-bin/modules/perception/multi_sensor_fusion/../../../_solib_local/_U_S_Smodules_Sperception_Smulti_Usensor_Ufusion_Cmulti_Usensor_Ufusion_Ulib___Umodules_Sperception_Smulti_Usensor_Ufusion/libmulti_sensor_fusion_lib.so: undefined symbol: _ZN6apollo10perception6fusion26MultiSensorFusionComponent16s_mutex_pkslots_E library_path:/apollo/bazel-bin/modules/perception/multi_sensor_fusion/libmulti_sensor_fusion.so

E0124 18:43:53.675557 6208 class_loader_utility.cc:234] mainboardshared library failed: /apollo/bazel-bin/modules/perception/multi_sensor_fusion/libmulti_sensor_fusion.so

用c++filt _ZN6apollo10perception6fusion26MultiSensorFusionComponent16s_mutex_pkslots_E

可以看到MultiSensorFusionComponent类的静态成员变量s_mutex_pkslots_未正确定义,在头文件中声明了:

static std::mutex s_mutex_pkslots_;

但在.cc文件中没有定义,增加std::mutex MultiSensorFusionComponent::s_mutex_pkslots_;即可消除链接错误。

相关推荐
Tairitsu_H10 小时前
[C++] 深入理解红黑树:封装set与map
开发语言·c++·set·map·红黑树·模拟实现
HugoStudio_SWAN10 小时前
洛谷 B4450 / B3867 / B3923 智慧购物、储蓄与做题——从程序到生活
c++·学习·程序人生·算法·生活
会周易的程序员12 小时前
5Draft(五帝)测试报告
服务器·c++·分布式·raft·共识算法·共识·算力服务器
UIU11412 小时前
scanf与cout的误区:探究其内部的机制
c++·学习·c#·scanf
闻缺陷则喜何志丹12 小时前
【栈 运算系统】P3719 [AHOI2017初中组] rexp|普及+
c++·算法··洛谷·运算系统
bnmoel13 小时前
C++ 基础入门篇(一):命名空间,输入&输出,缺省参数,函数重载
c++·函数重载·语法·命名空间·缺省参数
Zixhy13 小时前
多点巡检机器人项目技术总结
linux·c++·机器人·自动驾驶
Pointer Pursuit15 小时前
C++11特性(二)
前端·c++·算法
tudousisi22216 小时前
CSP 第3题训练 Day 5|CSP202509C HTTP 头信息|Blog A
c++
闻缺陷则喜何志丹17 小时前
【动态规划】P10726 [GESP202406 八级] 空间跳跃|普及+
c++·算法·动态规划·洛谷