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

gbm*_*ter 5 c++ compiler-construction embedded vtable freertos

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

虽然我已经克服了使用C++的大多数障碍,但首先使用编译器标志在C++中进行编译-x c++,定义new和delete运算符,确保编译器标志不会抛出异常,-fno-exception当它出现时我会遇到问题.来使用虚拟功能.

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

Quu*_*one 7

错误消息引用了一个名为class的事实__cxxabiv1表明您没有链接到您的平台的正确C++运行时.我对PSoC一无所知,但在更"正常"的平台上,如果你在链接时使用gcc(resp.clang)命令而不是g++(resp.clang++),就会发生这种错误.如果你-lc++没有-stdlib=libc++-lstdc++没有使用,或在手下的情况下-stdlib=libstdc++.

使用该-v选项检查链接器命令行,并尝试确切地找出它所引入的C++运行时库.它可能被命名为libcxxabi或者libcxxrt.

这里的人提供了在PSoC Creator中编译C++的逐步说明; 但他从来没有想出如何用C++运行时库链接,所以他所有的技巧都集中在如何删除从您的代码C++主义(-fno-rtti,-fno-exceptions,...).我同意网上似乎没有关于如何在PSoC中实际使用 C++的任何信息.

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

// 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
};
Run Code Online (Sandbox Code Playgroud)

或者许多链接器能够0x0通过命令行选项(如-Cor)定义未定义的符号--defsym.然而,这不仅是一个坏主意而且也不方便,因为您必须弄清楚vtable对象的实际(受损)名称是什么,并且链接器没有告诉您.(这是GCC,它可能就像__ZTVN10__cxxabiv117__class_type_infoE.)

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

具体来说,使用时出了-fno-rtti什么问题?