为什么Vtables没有在嵌入式平台上正确实现?

时间:2013-04-24 02:26:34

标签: c++ compiler-construction embedded vtable freertos

我正在为嵌入式系统(特别是PSoC 5,使用PSoC Creator)开发代码,并使用C ++编写。

虽然我已经克服了使用C ++的大多数障碍,但首先使用编译器标志-x c++在C ++中进行编译,定义new和delete运算符,确保不会使用编译器标志{{1在使用虚函数方面,我已经陷入了困境。

如果我尝试声明一个虚函数,编译器会给我错误-fno-exception。解决这个问题的唯一方法是使用编译器标志undefined reference to "vtable for __cxxabiv1::__class_type_info",它可以防止错误并使其成功编译。但是,如果我这样做,嵌入式程序在尝试运行重载的虚函数时会崩溃,我认为这是因为vtable不存在。

我不明白为什么你不能在嵌入式平台上实现vtables,因为它只是在成员对象之前或之后的内存中的额外空间(取决于确切的编译器)。

我尝试使用虚函数的原因是因为我想将FreeRTOS与C ++一起使用,而其他人已经通过使用虚函数实现了这一点(请参阅http://www.freertos.org/FreeRTOS_Support_Forum_Archive/July_2010/freertos_Is_it_possible_create_freertos_task_in_c_3778071.html进行讨论,并https://github.com/yuriykulikov/Event-driven_Framework_for_Embedded_Systems对于编写良好的嵌入式C ++ FreeRTOS框架)

1 个答案:

答案 0 :(得分:6)

错误消息引用名为__cxxabiv1的类的事实表明您没有链接到您的平台的正确 C ++运行时。我对PSoC一无所知,但在更“正常”的平台上,如果在链接时使用gcc(resp。clang)命令而不是{{{}},则可能会发生此类错误。 1}}(resp。g++);如果你使用clang++而没有-lc++-stdlib=libc++而没有使用-lstdc++,则会出现在手动情况下。

使用-stdlib=libstdc++选项检查链接器命令行,并尝试确切地找出它所引入的C ++运行时库。它可能被命名为-v或{{1} }。

This guy here提供了在PSoC Creator中编译C ++的逐步说明;但是他从来没有弄清楚如何与C ++运行时库建立联系,所以他的所有技巧都集中在如何从代码中移除 C ++主题(libcxxabilibcxxrt ,...)。我同意网上似乎没有关于如何在PSoC中实际使用 C ++的信息。

对于此特定的错误,您可以尝试自己定义缺失的符号:

-fno-rtti

或许多链接器能够通过命令行选项(例如-fno-exceptions// file "fix-link-errors.cpp" namespace __cxxabiv1 { class __class_type_info { virtual void dummy(); }; void __class_type_info::dummy() { } // causes the vtable to get created here }; )将未定义的符号定义为0x0。然而,这不仅是一个坏主意而且也不方便,因为您必须弄清楚vtable对象的实际(受损)名称是什么,并且链接器没有告诉您。 (这是GCC,它可能类似于-C。)

如果程序试图用vtable 任何事情,那么这些“解决方案”中的任何一个都会导致可怕的崩溃;但他们会关闭链接器,如果这就是你所关心的,你知道程序永远不会真正使用RTTI。但在这种情况下,在整个项目中始终使用--defsym就足够了。

使用__ZTVN10__cxxabiv117__class_type_infoE时会出现什么问题?