我只是遇到了以下错误:

(.gnu.linkonce。[内容]):定义 引用[方法][对象] 文件:(.gnu.linkonce。[内容]): 对' typeinfo for '的未定义引用 (名称)的

为什么可能会得到这些“未定义的引用typeinfo”链接错误之一? 有人能解释一下幕后发生了什么吗?


当前回答

如果你要将一个。so链接到另一个。so,还有一种可能性是在gcc或g++中使用"-fvisibility=hidden"进行编译。如果两个.so文件都是用"-fvisibility=hidden"构建的,并且key方法不相同。so作为另一个虚函数的实现,后者将看不到前者的虚表或typeinfo。对于链接器来说,这看起来像一个未实现的虚函数(就像paxdiablo和cdleary的答案一样)。

在这种情况下,必须为基类的可见性做出例外

__attribute__ ((visibility("default")))

在类声明中。例如,

class __attribute__ ((visibility("default"))) boom{
    virtual void stick();
}

当然,另一个解决方案是不使用"-fvisibility=hidden "。这使得编译器和链接器的事情变得复杂,可能会损害代码的性能。

其他回答

检查你的依赖是在没有-f-nortti的情况下编译的。

对于某些项目,你必须显式地设置它,比如在RocksDB中:

USE_RTTI=1 make shared_lib -j4

当混合使用-fno-rtti和-frtti代码时也会发生这种情况。然后,您需要确保在-frtti代码中访问type_info的任何类都使用-frtti编译了它们的key方法。这种访问可以发生在创建类的对象时,使用dynamic_cast等。

(来源)

如果你要将一个。so链接到另一个。so,还有一种可能性是在gcc或g++中使用"-fvisibility=hidden"进行编译。如果两个.so文件都是用"-fvisibility=hidden"构建的,并且key方法不相同。so作为另一个虚函数的实现,后者将看不到前者的虚表或typeinfo。对于链接器来说,这看起来像一个未实现的虚函数(就像paxdiablo和cdleary的答案一样)。

在这种情况下,必须为基类的可见性做出例外

__attribute__ ((visibility("default")))

在类声明中。例如,

class __attribute__ ((visibility("default"))) boom{
    virtual void stick();
}

当然,另一个解决方案是不使用"-fvisibility=hidden "。这使得编译器和链接器的事情变得复杂,可能会损害代码的性能。

我在这个错误上花了几个小时,虽然这里的其他答案帮助我理解发生了什么,但它们并没有解决我的特定问题。

我正在开发一个使用clang++和g++进行编译的项目。我没有使用clang++的链接问题,但得到了未定义的引用'typeinfo错误与g++。

重点是:在g++中,连接顺序很重要。如果你以不正确的顺序列出你想要链接的库,你会得到typeinfo错误。

有关与gcc/g++链接顺序的更多细节,请参阅这个SO问题。

有了这个错误消息,g++的链接器是在告诉你,当需要时,它无法为给定的类组装完整的静态typeinfo描述符。正如许多人已经指出的那样,这很可能是由于缺少虚函数的定义。

但不好的是,错误消息的顺序可能与直觉相反,“对typeinfo的未定义引用”出现在对缺失的虚拟定义的未定义引用之前。这里有一个例子,我刚刚经历过:

/usr/bin/ld: module.o:(.data.rel.ro+0x10): undefined reference to `typeinfo for type_xxx'
/usr/bin/ld: module.o:(.data.rel.ro+0x28): undefined reference to `typeinfo for type_xxx'
/usr/bin/ld: module.o:(.data.rel.ro+0x40): undefined reference to `typeinfo for type_xxx'
/usr/bin/ld: module.o:(.data.rel.ro+0x150): undefined reference to `type_xxx::has_property(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'

因此,type_xxx::has_property(const std::string&)的缺失定义仅作为第四个错误报告。因此,有时跳过那些不理解的错误消息,首先处理那些容易理解的错误消息是有好处的。因为在这种情况下,添加缺失的定义也会修复未定义typeinfo引用的问题。