Я занимаюсь разработкой кода для встроенной системы (в частности, 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)
Тот факт, что сообщение об ошибке относится к классу с именем __cxxabiv1
предполагает, что вы не ссылаетесь против правильного Среда выполнения C ++ для вашей платформы. Я ничего не знаю о PSoC, но на более «нормальных» платформах такая ошибка может произойти, если вы используете gcc
(Соотв. clang
) команда во время соединения вместо g++
(Соотв. clang++
); или при непредвиденных обстоятельствах, если вы использовали -lc++
без -stdlib=libc++
или же -lstdc++
без -stdlib=libstdc++
,
Использовать -v
возможность проверить командную строку компоновщика и попытаться выяснить, в какую именно библиотеку времени выполнения C ++ он загружается. Возможно, она будет иметь имя libcxxabi
или же libcxxrt
,
Этот парень здесь дает пошаговые инструкции по компиляции C ++ в PSoC Creator; но он так и не понял, как связываться с библиотекой времени выполнения C ++, поэтому все его советы сосредоточены на том, как Удалить C ++ isms из вашего кода (-fno-rtti
, -fno-exceptions
, …). Я согласен, что в Интернете нет никакой информации о том, как на самом деле использование C ++ с PSoC.
За это конкретный ошибка, вы всегда можете попробовать определить отсутствующий символ самостоятельно:
// 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
через параметры командной строки, такие как -C
или же --defsym
, Однако это не только плохая идея, но и неудобная, потому что вам нужно выяснить, каково действительное (искаженное) имя объекта vtable, и компоновщик вам этого не сказал. (Это GCC, это, вероятно, что-то вроде __ZTVN10__cxxabiv117__class_type_infoE
.)
Любое из этих «решений» приведет к ужасным сбоям, если программа когда-либо попытается делать что-нибудь с vtable; но они бы закрыли компоновщик, если это все, что вас волнует, и вы знали, что программа никогда не будет использовать RTTI. Но в этом случае должно быть достаточно использовать -fno-rtti
последовательно на весь ваш проект.
Что конкретно идет не так, когда вы используете -fno-rtti
?
Других решений пока нет …