Почему я не могу объявить класс в другой вкладке в Arduino IDE?

20

Я хотел переместить часть своего кода во вторую вкладку в Arduino IDE, чтобы лучше организовать вещи. Сначала я только пытался переместить функцию, и она работала нормально. Я мог вызвать функцию из setup()функции в моей главной вкладке, и не было никаких проблем при компиляции или загрузке.

Тем не менее, я попытался поместить целый класс во вторую вкладку, и внезапно это перестало работать. Например:

Вкладка 1:

TestClass obj;

void setup()
{
    obj.init();
}

void loop()
{
    //...
}

Вкладка 2:

class TestClass
{
public:
    void init()
    {
        //...
    }
};

Когда я попытался скомпилировать это, он дал мне следующие ошибки:

tab1:1: error: 'TestClass' does not name a type
tab1.ino: In function 'void setup()':
tab1:5: error: 'obj' was not declared in this scope

Почему он распознает функцию на другой вкладке, а не класс? Есть ли способ заставить его работать в Arduino IDE, или мне нужно использовать альтернативу, такую ​​как Eclipse?

Питер Блумфилд
источник
Это весь код? Какие имена файлов? Разве нет таких директив препроцессора, как #include?
asheeshr
Да, это весь код. Вкладки названы tab1и tab2соответственно. Имена были установлены с помощью IDE, поэтому основные файлы оба .ino.
Питер Блумфилд
Я начинаю ненавидеть покерные игры, которые делает Arduino IDE. То, что он добавляет в простоту использования по сравнению с AVR, он убирает, разбивая подобные вещи.
Cybergibbons

Ответы:

13

Невозможно объявить и использовать классы, объявленные в одном .pdeфайле в другом .pdeфайле, из среды разработки Arduino.

Один из обходных путей - сделать второй файл исходным файлом C ++ ( .cpp), а затем добавить #include "<filename>"директиву в начало первого файла.


Этот код компилируется правильно:

Вкладка 1:

#include "test.cpp"

TestClass obj;

void setup()
{
    obj.init();
}

void loop()
{
    //...
}

test.cpp:

class TestClass
{
public:
    void init()
    {
        //...
    }
};
asheeshr
источник
Спасибо за обходной путь. Он работает для основного примера, но, к сожалению, он не работает, если я добавлю какие-либо специфичные для Arduino вызовы в файл .cpp. Например, если TestClass::init()пытается вызвать pinMode(), компилятор жалуется, что pinModeне было объявлено в этой области. Есть ли способ получить доступ к функциям Arduino в моем классе?
Питер Блумфилд
6
@ PeterR.Bloomfield Добавьте #include <Arduino.h>в начало .cppфайла.
asheeshr
1
Я думаю, что нехорошо учить других включать исходные файлы ( #include "test.cpp"). Это работает, но может затормозить понимание процесса связывания. Только заголовочные файлы должны быть включены.
Марс
1
Я согласен с @Mars - лучшее решение - поместить объявление класса в файл .h, а определение (реализацию) - в файл .cpp. Итак, у вас есть два дополнительных файла в проекте. Это на самом деле нормальный способ обработки классов.
Ник Гэммон
6

Arduino IDE работает так, что он компилирует ваш код (код, который вы пишете в IDE) в качестве «основного» кода. Затем он извлекает код из всех импортированных вами библиотек и компилирует его вместе с основным кодом. Чтобы сделать то, что вы предлагаете, потребуется создать библиотеку для Arduino.

Вот еще немного информации о библиотеках Arduino:

http://arduino.cc/en/Guide/Libraries

А вот несколько о том, как создать библиотеку:

http://arduino.cc/en/Hacking/LibraryTutorial // это самый простой для понимания imo
http://playground.arduino.cc/Code/Library
http://www.divilabs.com/2013/03/ записи своего собственного Arduino-library.html #

Вот пример библиотеки, которую я написал https://github.com/jamolnng/Arduino/tree/master/libraries/ShiftRegister, поскольку вы можете видеть, что нет проблем с вызовом функций Arduino из файла .cpp (я знаю, проверил библиотеку)

Джесси Ланинг
источник
3
Также возможно просто создавать .hи .cppфайлы в вашем основном проекте, без необходимости создавать отдельную библиотеку.
микротерион