Что именно делает препроцессор Arduino?
Arduino утверждает, что является «языком», а не просто «инфраструктурой приложений», и файлы Arduino имеют собственное расширение .ino
. Язык, очевидно, C++, но не совсем. Насколько я понимаю, у Arduino есть какой-то специальный препроцессор, который преобразует файлы .ino
в файлы C++ перед их компиляцией.
Мой вопрос: что точно делает этот препроцессор? В чем именно разница между «языком Arduino» и настоящим C++? В документации Arduino это, кажется, замалчивается.
В частности, со мной происходили странные вещи, когда я пытался определить свои собственные классы в своем скетче. Трудно понять, что я делаю не так, когда язык нигде не указан.
@user31708, 👍2
Обсуждение2 ответа
Лучший ответ:
По сути, он делает четыре вещи:
- Он добавляет
#include <Arduino.h>
в начало вашего файла, что дает вам доступ ко всем классам, функциям и определенным переменным/макросам API. - Он объединяет все файлы INO в один монолитный файл (в том же порядке, что и вкладки в окне),
- Он сопоставляет записи
#include
с библиотеками и добавляет файлы из этих библиотек в список файлов для компиляции, и - Он сканирует ino-файлы в поисках функций и добавляет к ним прототипы в начало вашего файла.
Последнее может вызвать проблемы. Исторически сложилось так, что прототипы никогда не помещались в нужное место, и если вы когда-нибудь передали в функцию структуру, придуманную вами самим, она бы ужасно сломалась. Сегодня он работает лучше, но все еще не идеален на 100 %.
По сути, это означает, что вам не нужно придерживаться правила C/C++ «Вы должны определить это, прежде чем использовать». Что, конечно, делает программистов ленивыми.
и он объединяет все ino-файлы проекта в один файл, начиная с ino-файла с тем же именем, что и у папки проекта, а затем остальных ino-файлов в алфавитном порядке (это тот же порядок, что и вкладки в IDE), @Juraj
Ах да, это тоже., @Majenko
См. мой ответ: Как IDE организует вещи
Я не уверен, что ответы, содержащие только ссылки и относящиеся к ссылке Stack Exchange, приемлемы. Если это не так, вот первая часть ответа:
Вот как IDE организует ваш «скетч»:
- Основной файл
.ino
имеет то же имя, что и папка, в которой он находится. Итак, дляfoobar.ino
вfoobar
папка — основной файл foobar.ino. - Все остальные файлы
.ino
в этой папке объединяются в алфавитном порядке в конце основного файла (независимо от того, где находится основной файл, в алфавитном порядке). - Этот объединенный файл становится файлом
.cpp
(например,foobar.cpp
) — он помещается во временную папку компиляции. - Препроцессор «услужливо» генерирует прототипы функций, которые он находит в этом файле.
- Основной файл сканируется на наличие директив
#include <libraryname>
. Это заставляет IDE также копировать все соответствующие файлы из каждой (упомянутой) библиотеки во временную папку и генерировать инструкции для их компиляции. - Любые файлы
.c
,.cpp
или.asm
в папке скетча добавляются в процесс сборки как отдельные единицы компиляции (которые то есть они компилируются обычным способом в отдельные файлы) - Все файлы
.h
также копируются во временную папку компиляции, поэтому на них можно ссылаться в файлах .c или .cpp. - Компилятор добавляет в процесс сборки стандартные файлы (например,
main.cpp
) - Затем процесс сборки компилирует все указанные выше файлы в объектные файлы.
- Если фаза компиляции прошла успешно, они скомпонуются вместе со стандартными библиотеками AVR (например, предоставив вам
strcpy
и т. д.)
Побочным эффектом всего этого является то, что вы можете считать основной скетч (файлы .ino) по сути написанным на C++. Однако генерация прототипа функции может привести к неясным сообщениям об ошибках, если вы не будете осторожны.
Спасибо! Откуда вы узнали всю эту информацию?, @user31708
Наблюдение за тем, какие файлы копируются во временный каталог, и просмотр команд, выполняемых при включенной «подробной» компиляции., @Nick Gammon
Где находятся временные файлы? Можете ли вы настроить Arduino IDE так, чтобы их можно было легко просматривать?, @NeilenMarais
Если вы включите «подробную компиляцию», вы сможете увидеть, где находятся временные файлы., @Nick Gammon
- Цикл While не прерывается
- как отправить аргумент объектам ESP8266WebServer в функции
- Как изменить переменную/скетч с помощью графического интерфейса
- оператор if не работает с дробью, но работает с десятичным эквивалентом
- Обновите атрибут класса с помощью attachInterrupt
- Загрузка Arduino Nano дает ошибку: avrdude: stk500_recv(): programmer is not responding
- Какие накладные расходы и другие соображения существуют при использовании структуры по сравнению с классом?
- Что лучше использовать: #define или const int для констант?
Конвертер Arduino ino в cpp не затрагивает ваши файлы cpp и h. Он преобразует только файл ino в файл cpp, как описал Маженко в своем ответе., @Juraj
*Со мной происходили странные вещи* - можете ли вы привести пример?, @Nick Gammon
@NickGammon Это было давно, поэтому я не помню точное сообщение об ошибке. Но я подозреваю, что это было вызвано автоматически созданными прототипами. (т.е. функция принимает структуру или класс в качестве аргумента, а прототип вставляется перед объявлением этой структуры или класса), @user31708