Функция, объявленная в другом файле, не распознана (undefined reference to)
Я создаю проект arduino с несколькими файлами, но компилятор не может распознать функцию. Я использую arduino-cli версии 0.10.0
Это ошибка, которую я получил
неопределенная ссылка на pin_init() collect2.exe: ошибка: ld вернул 1 ошибку состояния выхода во время сборки: состояние выхода 1
Это команда:
arduino-cli compile -b arduino:avr:uno C:\Users\Cioccarelli\Desktop\transmitterCopy\main
главная.ino:
#include "C:\Users\Cioccarelli\Desktop\transmitter\automation\automation.h"
void setup() {
pin_init();
}
void loop() {}
автоматизация.ч:
#pragma once
// Здесь хранятся входные контакты компонентов, они помещаются сюда с помощью функции
byte pinSetup[0];
byte pinSetupSize = 0;
// Эта функция вызывается в настройке() и инициализирует каждый контакт, указанный в pinSetup [], как входной
void pin_init();
automation.cpp:
#include "C:\Users\Cioccarelli\Desktop\transmitter\automation\automation.h"
extern pinSetup;
extern pinSetupSize;
void pin_init() {
for (int i = 0; i < pinSetupSize; i++)
pinMode(i, INPUT);
}
Я думаю, что эта проблема может быть связана с тем фактом, что я не совсем понимаю включение файлов, но я не нашел ничего полезного в своих исследованиях
Обновление: сегодня я перестроил проект под другими названиями и вырезал все, что не было связано с проблемой, в надежде идентифицировать ее.
новая основная:
#include "C:\Arduino\transmitter\nightmare\nightmare.h"
void setup() {
pin_init();
}
void loop() {}
новая автоматизация.h (кошмар.ч):
#pragma once
// Эта функция вызывается в setup() и инициализирует каждый указанный контакт
//в pinSetup[] в качестве входного
void pin_init();
новое automation.cpp (nightmare.cpp):
#include "C:\Arduino\transmitter\nightmare\nightmare.h"
void pin_init() {}
новая структура файлов:
Я также сделал копию и внес некоторые изменения, чтобы он мог стать файлом C++ (заменив setup() на main() и заменив каждый тип "байт" на "int").
Затем я поместил его в Visual studio, он отлично скомпилировался. IDE arduino выдает ту же ошибку
3 ответа
У компилятора не было проблем, у компоновщика были. То есть, как только ваша основная функция была скомпилирована (правильно) для вызова pin_init(), загрузчик попытался собрать все скомпилированные модули и связать вызовы, которые не были выполнены локально - в одном файле - с функциями, определенными в другом модуле. Именно тогда было сгенерировано это сообщение. Такого определения функции найдено не было, несмотря на объявление ее в main.ino.
Если вы можете скомпилировать это с помощью Arduino IDE, посмотрите, что он делает: он будет компилировать каждый из ваших модулей исходного кода по одному за раз. Затем свяжите все скомпилированные версии ваших модулей вместе, чтобы создать шестнадцатеричный файл (который в конечном итоге будет загружен в Arduino). Вам нужно имитировать это при компиляции и загрузке из командной строки.
Обновление:
сегодня я перестроил проект под другими названиями
Ваш файл .cpp находится в той же папке, что и файл .ino? Или в другой папке, например в папке, содержащей ваш файл .h? Я подозреваю, что это последнее. Когда я создавал ваш проект в среде IDE Arduino, он удался, когда .ino и .h находились в одной папке, произошел сбой точно так, как вы описали, когда я переместил файл .cpp туда, где находится файл .h.
Решение возвращается к тому, что я предлагал ранее; что определение pin_input() не было найдено, так как файл .cpp, содержащий его, не был замечен IDE (или вашим компилятором командной строки) и, следовательно, не был скомпилирован и связан. Каждый из ваших файлов должен быть скомпилирован, и все они вместе должны быть связаны, чтобы внешние вызовы были удовлетворены.
С помощью IDE поместите файлы .ino и .cpp вашего проекта в одну папку, чтобы IDE видела и компилировала каждый из них и знала, какие файлы нужно связать. Среда IDE не даст вам большой гибкости для поиска ваших файлов .cpp.
С помощью компилятора командной строки вы можете поместить свои файлы куда угодно, выполнить отдельную[1] компиляцию только для каждого из них, затем выполнить еще один запуск компонента компоновщика[2], назвав все скомпилированные блоки (IDE называет их как .d) и указав путь к папке(папкам) вашей библиотеки.
[1] Я не знаком с синтаксисом командной строки компилятора командной строки; возможно, вы можете указать несколько компиляций с помощью одной команды.
[2] Опять же, укажите, нужно ли вам вызывать компоновщик с помощью той же команды, но с переключателем параметров только для ссылок, или вам нужно будет вызвать компоновщик самостоятельно в командной строке.
IDE arduino выдает ту же ошибку, я внес некоторые дополнения в вопрос, @Michele Cioccarelli
Среда IDE Arduino (и я предполагаю, что arduino-cli ведет себя так же) попытается связать в вашем проекте каждый исходный файл, который находится в том же каталоге, что и файл main .ino.
Попробуйте это: избавьтесь от вложенных папок “автоматизация” и “основные”, поместите все в корень проекта и попробуйте построить заново. Если у вас окажется слишком много материала в корневом каталоге, вы можете рассмотреть возможность создания собственных библиотек, но это на другой день...
Я получил очень похожую ошибку, когда забыл объявить все переменные в "class.cpp". В "class.h" было объявление "класс XYZ { байтовый тест; };", но в "class.cpp" Я забыл написать "байт XYZ::тест;".
Я не вижу сходства, @Juraj
- Ошибка переменной does not name a type!
- Ошибка: Does not name a type
- Сообщение об ошибке: "exit status 1 expected initializer before 'void'."
- C++ против языка Arduino?
- Как использовать SPI на Arduino?
- Какие накладные расходы и другие соображения существуют при использовании структуры по сравнению с классом?
- Ошибка: expected unqualified-id before 'if'
- Что лучше использовать: #define или const int для констант?
Чтобы быть простым, поместите все файлы в один каталог и сделайте "#включить "automation.h"". Поскольку у вас небольшой проект, это может сработать., @Linny
@Linny Я знаю, что это сработает, но я хочу сделать это таким образом, потому что хочу научиться управлять несколькими каталогами и потому что это очень ранняя стадия проекта, в будущем такое решение будет работать очень плохо, @Michele Cioccarelli