使用-frtti仍出现typeinfo未定义引用,仅-fno-rtti可行的问题排查
问题分析与解决思路
核心问题原因排查
出现undefined reference to typeinfo seeta::v3::QualityOfBrightness错误,本质是编译器生成RTTI信息时,找不到基类QualityOfBrightness对应的typeinfo符号。以下是几个关键排查方向:
1. 第三方库的RTTI未全局生效
虽然你确认CMakeOutput.log中存在-frtti,但需注意:
- 检查库的所有编译模块是否都启用了RTTI。部分子模块可能单独配置了
-fno-rtti,导致最终库文件缺失QualityOfBrightness的typeinfo符号。 - 可以通过命令
nm -D [第三方库文件名] | grep typeinfo验证,若输出中没有typeinfo for seeta::v3::QualityOfBrightness,说明库确实未生成该符号,需重新检查CMake配置,确保全局开启RTTI且无局部覆盖。
2. 虚函数实现的编译选项不一致
QualityOfBrightness的析构函数和check函数都是带SEETA_API的虚函数,需确认:
- 这些函数的实现代码是在启用RTTI的环境下编译的。如果实现文件(如
QualityOfBrightness.cpp)编译时被添加了-fno-rtti,即使头文件声明正确,也会导致typeinfo缺失。 - 查看库的编译日志,确认编译对应cpp文件时的选项中没有
-fno-rtti。
3. 命名空间不匹配
错误信息中显示的命名空间是seeta::v3,但你提供的类定义未显式包含v3命名空间,需:
- 检查
seeta/QualityOfBrightness.h的实际内容,确认QualityOfBrightness是否被包裹在seeta::v3命名空间内。若存在,你的代码中using namespace seeta;未覆盖v3,会导致继承的类与库中实际类不在同一命名空间,链接时找不到对应typeinfo。
4. 编译器ABI兼容性问题
gcc10.2的RTTI生成逻辑与旧版本存在细微差异,需确认:
- 第三方库是否使用同一版本的gcc(gcc10.2)编译。若库由更低版本gcc编译,即使开启RTTI,也可能出现typeinfo符号不兼容的情况。
临时 workaround(优先排查核心原因)
如果暂时无法修复第三方库的RTTI问题,可在自定义类中添加一个空虚函数,强制编译器生成typeinfo:
class Handler: public QualityOfBrightness { public: Handler() : QualityOfBrightness() {}; ~Handler() override {}; QualityResult check ( const SeetaImageData &image, const SeetaRect &face, const SeetaPointF *points, const int32_t N) override { return QualityResult (QualityLevel::HIGH); }; // 强制生成typeinfo的临时方案 virtual void dummy() {}; };
附:问题相关代码
自定义类示例代码
#include <seeta/QualityOfBrightness.h> using namespace seeta; class Handler: public QualityOfBrightness { public: Handler() : QualityOfBrightness() {}; ~Handler() {}; QualityResult check ( const SeetaImageData &image, const SeetaRect &face, const SeetaPointF *points, const int32_t N) override { return QualityResult (QualityLevel::HIGH); }; }; int main (void) { Handler a; }
第三方库类定义
class QualityOfBrightness : public QualityRule { public: using self = QualityOfBrightness; using supper = QualityRule; SEETA_API QualityOfBrightness(); SEETA_API QualityOfBrightness (float v0, float v1, float v2, float v3); SEETA_API ~QualityOfBrightness() override; SEETA_API QualityResult check ( const SeetaImageData &image, const SeetaRect &face, const SeetaPointF *points, const int32_t N) override; private: QualityOfBrightness (const QualityOfBrightness &) = delete; QualityOfBrightness &operator= (const QualityOfBrightness &) = delete; private: void *m_data; }; class QualityRule { public: using self = QualityRule; virtual ~QualityRule() = default; virtual QualityResult check ( const SeetaImageData &image, const SeetaRect &face, const SeetaPointF *points, int32_t N) = 0; };
内容的提问来源于stack exchange,提问作者sixsixqaq
相关产品推荐
相关产品推荐

