我只是遇到了以下错误:
(.gnu.linkonce。[内容]):定义 引用[方法][对象] 文件:(.gnu.linkonce。[内容]): 对' typeinfo for '的未定义引用 (名称)的
为什么可能会得到这些“未定义的引用typeinfo”链接错误之一? 有人能解释一下幕后发生了什么吗?
我只是遇到了以下错误:
(.gnu.linkonce。[内容]):定义 引用[方法][对象] 文件:(.gnu.linkonce。[内容]): 对' typeinfo for '的未定义引用 (名称)的
为什么可能会得到这些“未定义的引用typeinfo”链接错误之一? 有人能解释一下幕后发生了什么吗?
当前回答
检查你的依赖是在没有-f-nortti的情况下编译的。
对于某些项目,你必须显式地设置它,比如在RocksDB中:
USE_RTTI=1 make shared_lib -j4
其他回答
在我的情况下,这纯粹是一个库依赖问题,即使我有dynamic_cast调用。在makefile中添加了足够的依赖后,这个问题就消失了。
我有同样的错误时,我的接口(与所有纯虚函数)需要一个更多的函数,我忘记“空”它。
我有
class ICommProvider { public: /** * @brief If connection is established, it sends the message into the server. * @param[in] msg - message to be send * @return 0 if success, error otherwise */ virtual int vaSend(const std::string &msg) = 0; /** * @brief If connection is established, it is waiting will server response back. * @param[out] msg is the message received from server * @return 0 if success, error otherwise */ virtual int vaReceive(std::string &msg) = 0; virtual int vaSendRaw(const char *buff, int bufflen) = 0; virtual int vaReceiveRaw(char *buff, int bufflen) = 0; /** * @bief Closes current connection (if needed) after serving * @return 0 if success, error otherwise */ virtual int vaClose(); };
Last vaClose不是虚拟的,所以编译时不知道从哪里获得它的实现,因此感到困惑。我传达的信息是:
…TCPClient.o:(.rodata+0x38): undefined reference to ' typeinfo for ICommProvider'
简单的更改
virtual int vaClose();
to
virtual int vaClose() = 0;
修复了问题。希望能有所帮助
引用gcc手册:
对于多态类(具有虚函数的类),type_info对象与虚表[…对于所有其他类型,我们在使用type_info对象时写出type_info对象:当将' typeid'应用到表达式、抛出对象或在catch子句或异常规范中引用类型时。
在同一页稍早的地方
如果类声明了任何非内联、非纯虚函数,则选择第一个虚函数作为类的“key方法”,虚表只在定义key方法的转换单元中发出。
因此,当“key方法”缺少它的定义时,就会发生这个错误,正如前面提到的其他答案。
如果你要将一个。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 "。这使得编译器和链接器的事情变得复杂,可能会损害代码的性能。
当混合使用-fno-rtti和-frtti代码时也会发生这种情况。然后,您需要确保在-frtti代码中访问type_info的任何类都使用-frtti编译了它们的key方法。这种访问可以发生在创建类的对象时,使用dynamic_cast等。
(来源)