6

I am developing code for an embedded system (specifically, the PSoC 5, using PSoC Creator), and writing in C++.

While I've overcome most hurdles with using C++ , first off compiling in C++ using the compiler flag -x c++, defining the new and delete operators, making sure exceptions aren't thrown with the compiler flag -fno-exception, I've come to a brick wall when it comes to using virtual functions.

If I try and declare a virtual function, the compiler gives me the error undefined reference to "vtable for __cxxabiv1::__class_type_info". The only way to get around this is to use the compiler flag -fno-rtti, which prevents the error and makes it compile successfully. However, if I do that, the embedded program crashes when trying to run the overloaded virtual function, and I'm thinking this is because the vtable does not exist.

I don't see why you shouldn't be able to implement vtables on an embedded platform, since all it is a extra space in memory before or after member objects (depending on the exact compiler).

The reason I am trying to use virtual functions is because I am wanting to use FreeRTOS with C++, and other people have implemented this by using virtual functions (see http://www.freertos.org/FreeRTOS_Support_Forum_Archive/July_2010/freertos_Is_it_possible_create_freertos_task_in_c_3778071.html for the discussion, and https://github.com/yuriykulikov/Event-driven_Framework_for_Embedded_Systems for a well written embedded C++ FreeRTOS framework)

4

1 回答 1

10

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

使用该-v选项检查您的链接器命令行,并尝试找出它正在拉入的确切 C++ 运行时库。它可能会被命名为libcxxabior 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
};

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

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

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

于 2013-04-25T21:42:33.627 回答