При создании проекта с использованием C++, часто подключаются разные файлы .c или .cpp.
KEIL между разными файлами может не видеть внешние функции и сообщаться об этом ошибкой: Error: L6218E: Undefined symbol xxxxxxxxxxxxxxxxxxxx (referred from main.o).
Это связано с тем что линковщик ругается на компоновку. Не видит из других модулей.
Ключевое слово extern
объявляет переменную или функцию и указывает, что она имеет внешние компоновки (ее имя будет видимым не только в пределах файла, в котором она определена, но и в других файлах). Когда выполняется изменение переменной, ключевое слово extern
обозначает, что переменная имеет статическую длительность (она выделяется в начале программы и высвобождается при завершении). Переменная или функция может быть определена в другом исходном файле или позднее в том же самом файле. Объявления переменных и функций в области видимости файла являются внешними по умолчанию.
Если в C++ ключевое слово extern
используется со строковым объектом, это означает, что для деклараторов используются соглашения о компоновках другого языка. К функциям и данным C можно обращаться, только если ранее они были объявлены как имеющие компоновки C. Однако они должны быть определены в блоке трансляции, который компилируется отдельно.
Чтобы вызвать функцию C из C++, используйте следующую нотацию преобразования типов:
extern "C" void my_func (void);
Это сообщает компоновщику, что для функции my_func требуется компоновка для модуля на языке С++ с соглашением языка С.
Есть два пути решения:
1. В модуле обьявить стиль C для всех внешних ссылок.
В файле MyFile.h нужно добавить:
#include «cmsis_os2.h»
#include «stm32f10x.h»#ifdef __cplusplus
extern «C» {
#endifextern uint16_t BUF;
extern void TFT_START(void);#define TFT_RST_LOW GPIOB->BRR = (1
#define TFT_RST_HIGH GPIOB->BSRR = (1#ifdef __cplusplus
}
#endif
Это позволит компилировать в зависимости от настроек компилятора.
2. Это самостоятельно указывать соглашение для каждой внешней ссылки.
К пример есть два модуля main.cpp и display.c
В модулей main.cpp есть реализация функции Delay, чтобы модуль display.c ее увидел нужно обьявить ее прототип как внешняя в модуле main.h.
extern void Delay (uint32_t Count);
Компоновщик не увидит ее из-за разницы соглашений, для этого добавляем соглашение.
extern «C» void Delay (uint32_t Count);
После этого компоновщик будет видеть ее и функция станет доступна другим модулям которые используют ее.
В случае, если модули используются одинаковые, тогда достаточно одного обьявления прототипа в модуле display.c
extern void Delay (uint32_t Count);
Удачной компиляции без ошибок!
Оставить ответ
Вы должны быть авторизованы чтобы размещать комментарии.