Як IDE впорядковує речі
По-перше, це те, як 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 ++ у всіх намірах і цілях. Однак генерація прототипу функції може призвести до неясних повідомлень про помилки, якщо ви не будете обережні.
Уникання химерностей перед процесором
Найпростіший спосіб уникнути цих ідіосинкразій - залишити основний ескіз порожнім (а не використовувати жодні інші .ino
файли). Потім зробіть іншу вкладку ( .cpp
файл) і вкладіть у неї свої речі так:
#include <Arduino.h>
// put your sketch here ...
void setup ()
{
} // end of setup
void loop ()
{
} // end of loop
Зверніть увагу, що вам потрібно включити Arduino.h
. IDE робить це автоматично для основного ескізу, але для інших підрозділів компіляції це потрібно зробити. Інакше він не дізнається про такі речі, як String, апаратні регістри тощо.
Уникнення установки / основної парадигми
Вам не доведеться працювати з концепцією установки / циклу. Наприклад, ваш .cpp файл може бути:
#include <Arduino.h>
int main ()
{
init (); // initialize timers
Serial.begin (115200);
Serial.println ("Hello, world");
Serial.flush (); // let serial printing finish
} // end of main
Примусове включення бібліотеки
Якщо ви працюєте з концепцією "порожній ескіз", вам все одно потрібно включити бібліотеки, які використовуються в іншому місці проекту, наприклад, у ваш основний .ino
файл:
#include <Wire.h>
#include <SPI.h>
#include <EEPROM.h>
Це тому, що IDE сканує лише основний файл для використання бібліотеки. Ефективно ви можете розглядати головний файл як "проектний" файл, який визначає, які зовнішні бібліотеки використовуються.
Визначення питань
Не називайте свій головний ескіз "main.cpp" - IDE включає власний main.cpp, тому у вас буде дублікат, якщо ви це зробите.
Не називайте свій .cpp-файл із тим самим іменем, що і основний .ino-файл. Оскільки файл .ino фактично стає .cpp-файлом, це також призведе до зіткнення імені.
Оголошення класу стилю C ++ у тому самому, єдиному .ino-файлі (чули, але не бачили, як працює - це можливо навіть)?
Так, це компілює ОК:
class foo {
public:
};
foo bar;
void setup () { }
void loop () { }
Однак вам, мабуть, найкраще дотримуватися звичайної практики: розміщуйте свої декларації у .h
файлах, а свої визначення (реалізації) у файлах .cpp
(або .c
).
Чому "напевно"?
Як показує мій приклад, ви можете зібрати все разом в один файл. Для великих проектів краще бути більш організованими. Врешті-решт, ви потрапляєте на сцену в проекті середнього та великого розміру, де ви хочете розділити речі на «чорні скриньки» - тобто клас, який робить одне, робить це добре, тестується і є самостійним ( наскільки це можливо).
Якщо цей клас потім використовується у кількох інших файлах у вашому проекті, саме тут .h
і .cpp
грають окремі файли.
.h
Файл оголошує клас - тобто, він забезпечує досить деталей для інших файлів , щоб знати , що він робить, які функції у нього є, і як вони називаються.
У .cpp
файл визначає (реалізує) клас - тобто, він на самому ділі забезпечує функції і статичні члени класу, які роблять клас робити свою справу. Оскільки ви хочете реалізувати його лише один раз, це знаходиться в окремому файлі.
.h
Файл , що входить в інші файли. .cpp
Файл компілюється один раз в IDE для реалізації функцій класу.
Бібліотеки
Якщо ви дотримуєтесь цієї парадигми, то ви готові перенести весь клас ( файли .h
та .cpp
файли) в бібліотеку дуже легко. Тоді його можна розділити між кількома проектами. Все , що потрібно , щоб зробити папку (наприклад. myLibrary
) І поставити .h
і .cpp
файли в ній (наприклад, myLibrary.h
а myLibrary.cpp
) , а потім помістити цю папку всередині libraries
папки в папку , в якій зберігаються ваші ескізи (етюдник папку).
Перезавантажте IDE, і тепер він знає про цю бібліотеку. Це дійсно тривіально просто, і тепер ви можете ділитися цією бібліотекою у кількох проектах. Я цим багато займаюся.
Трохи докладніше тут .