我正在为嵌入式系统(特别是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框架)
答案 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 ++主题(libcxxabi
,libcxxrt
,...)。我同意网上似乎没有关于如何在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
时会出现什么问题?