Почему Vtables не внедряется правильно на встроенной платформе?

Я занимаюсь разработкой кода для встроенной системы (в частности, 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)

5

Решение

Тот факт, что сообщение об ошибке относится к классу с именем __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?

6

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]