Функция, объявленная в другом файле, не распознана (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);
}

Я думаю, что эта проблема может быть связана с тем фактом, что я не совсем понимаю включение файлов, но я не нашел ничего полезного в своих исследованиях

On the left is the file setup

Обновление: сегодня я перестроил проект под другими названиями и вырезал все, что не было связано с проблемой, в надежде идентифицировать ее.

новая основная:

#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 выдает ту же ошибку

, 👍1

Обсуждение

Чтобы быть простым, поместите все файлы в один каталог и сделайте "#включить "automation.h"". Поскольку у вас небольшой проект, это может сработать., @Linny

@Linny Я знаю, что это сработает, но я хочу сделать это таким образом, потому что хочу научиться управлять несколькими каталогами и потому что это очень ранняя стадия проекта, в будущем такое решение будет работать очень плохо, @Michele Cioccarelli


3 ответа


1

У компилятора не было проблем, у компоновщика были. То есть, как только ваша основная функция была скомпилирована (правильно) для вызова 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


0

Среда IDE Arduino (и я предполагаю, что arduino-cli ведет себя так же) попытается связать в вашем проекте каждый исходный файл, который находится в том же каталоге, что и файл main .ino.

Попробуйте это: избавьтесь от вложенных папок “автоматизация” и “основные”, поместите все в корень проекта и попробуйте построить заново. Если у вас окажется слишком много материала в корневом каталоге, вы можете рассмотреть возможность создания собственных библиотек, но это на другой день...

,

0

Я получил очень похожую ошибку, когда забыл объявить все переменные в "class.cpp". В "class.h" было объявление "класс XYZ { байтовый тест; };", но в "class.cpp" Я забыл написать "байт XYZ::тест;".

,

Я не вижу сходства, @Juraj