IAR: совместное использование кода C и кода C++ |
![]() |
Добавил(а) microsin |
Вы можете захотеть вызывать C-функции из своего проекта на C++. Альтернативно Вы также можете захотеть вызывать функции C++ из проекта C. В этой статье (перевод [1]) описывает несколько моментов, которые следует учесть, когда смешиваете код C и C++. Обратите внимание, что это руководство не претендует на полноту, однако показывает некоторые общие проблемы и способы их решения. Следует учесть следующее: 1. Необходимо использовать линковку проекта в стиле языка C (C-linkage). Для этого в заголовочные файлы поместите extern "C" { // здесь декларации Ваших функций }. Имейте в виду, что это требуется сделать как для заголовочных файлов C++, так и для заголовочных файлов C: • Чтобы C-функция могла вызвать функцию C++. 2. У языка C++ более строгая проверка типов. Для примера рассмотрим следующую функцию C: void LCD_DisplayString(const uint8_t *text); Эту функцию на языке C можно вызвать так: LCD_DisplayString("RTOS START");
На языке C++ это не сработает, понадобится сделать приведение "RTOS START" к типу uint8_t* (из типа char*), чтобы подобный вызов мог скомпилироваться. Есть решение лучше, чем приведение типа (cast), см. пункт 3. 3. Оберните C-интерфейсы в классы C++. Например, вышеупомянутая функция LCD_DisplayString может быть обернута в класс LCD::DisplayString(). С помощью перезагрузки языка C++ (overloading), преобразование типа между char* и uint8_t* можно скрыть внутри методов класса LCD: void LCD::DisplayString(const char *text); void LCD::DisplayString(const uint8_t *text); Другими словами, таким способом в своем коде C++ Вы можете везде избежать кастинга типов. 4. В некоторых областях C++ ведет себя по-другому. Например, переменная: const int myglobal; ... не является глобальной в C++, поскольку глобальные константы C++ линкуются статически. Также, например, volatile-доступ не обязательно выполняется на C++: void access(void) { *((volatile uint8_t*)0x20000000); } В то же время на C осуществляется volatile-доступ (спецификации языков C и C++ отличаются, когда к объекту осуществляется доступ в void-контексте). Чтобы избежать проблем, убедитесь, что компилируете чистый код C как C (например, код RTOS или BSP с расширением имен файлов ".c"). Имейте в виду, что компилятор C++ выдаст предупреждение на приведенный выше код: "Warning[Pe174]: expression has no effect" (выражение не имеет никакого действия). 5. Если Вы хотите использовать C-код в своих приложениях C++, рассмотрите возможность сборки C-кода в отдельном проекте (как библиотека). Вы можете поместить проект библиотеки C в том же рабочем пространстве (workspace), что и проект C++, чтобы можно было быстро переключаться между проектами. Пример такого смешивания проектов см. в архиве [3]. Если сравнивать встраивание C-кода в группу C++ проекта с библиотекой, библиотека дает следующие преимущества: • Четкое разделение между разными опциями компилятора. 6. Если Ваша библиотека C это RTOS, то есть дополнительная трудность с использованием кучи RTOS, кода запуска (RTOS startup) и т. д. [2]. Часто поставщик RTOS может помочь с предоставлением примеров на C++, документацию и/или код. И снова, если код RTOS написан на C, компилируйте его как C, чтобы избежать проблем. Technical Note 93670 C-RUN - Non-checked code (bounds checking) site:iar.com. [Ссылки] 1. Technical Note 46551 Mixing C and C++ site:iar.com. |