Множественная ошибка определения при связывании firmware.elf
Я просто не могу понять, как правильно работать с несколькими файлами. Мой код стал довольно большим, поэтому я решил разделить все классы на один файл каждый. Итак, у меня осталось 6 файлов:
dataHandler.cpp
fileHandler.cpp
header.cpp
main.cpp
request.cpp
sensorData.cpp
header.cpp включает все файлы заголовков, а main.cpp — функции setup() иloop().
Visual Studio Code не показывает ошибок при компиляции. Включаемые защиты имеют соглашение об именах: CLASSNAME_INCG
Например, в моем файле main.cpp есть что-то вроде:
#ifndef HEADER_INCG
#include "header.cpp"
#define HEADER_INCG
#endif
#ifndef SENSORDATA_INCG
#include "SensorData.cpp"
#define SENSORDATA_INCG
#endif
#ifndef DATAHANDLER_INCG
#include "DataHandler.cpp"
#define DATAHANDLER_INCG
#endif
setup()
{
...
}
...
При входе в файл класса он определяется следующим образом (fileHandler.cpp):
#ifndef HEADER_INCG
#include "header.cpp"
#define HEADER_INCG
#endif
#ifndef FILEHANDLER_INCG
#define FILEHANDLER_INCG
class FileHandler{
...
}
#endif
Итак, вкратце Я включаю заголовочный файл в каждый файл, окружая его защитой. Если бы я не включил его, я бы получил ошибки, из-за которых отсутствуют важные библиотеки, такие как Serial и т. д. Но при включении заголовка в каждый файл компиляция работает нормально, но когда дело доходит до связывания файлов вместе, я получаю ошибку с несколькими определениями.
Так как же я могу определить файл заголовка только один раз для всех файлов, хотя он мне нужен в каждом файле?
@Cowboy_Patrick, 👍1
Обсуждение1 ответ
Лучший ответ:
Правило №1:
Расширение заголовочного файла — «.h». Файлы с расширением «.cpp» обычно компилируются как отдельные единицы компиляции в объектный файл. Если у вас есть какое-либо определение функции (= объявление + реализация) или любая глобальная переменная в других объектных файлах, она не сможет связать.Правило №2:
Никаких определений в заголовках — переменные и функции вызовут эту ошибку, если вы включите файл .h в другие файлы .cpp. Если вам нужна суперглобальная переменная, вам нужно использовать объявление с модификатором extern и определить ее в одном из файлов .cpp. Но только один! Также в заголовочном файле могут быть только прототипы функций (объявления). Реализация должна быть только один раз в одном из файлов «.cpp».
Обычно это находится в первой главе книг по изучению C/C++.
Очень короткий пример:
// myLib.h
#ifndef _myLib_h_guard_
#define _myLib_h_guard_
void myFunction(); // прототип функции (объявление)
extern int mySuperGlobalVariable; // переменная объявлена как extern, где-то должно быть ее определение
class MyClass {
public:
int someMethod(); // объявление метода
int anotherMethod() { return 1; } // определение внутри класса работает, но иногда становится менее читабельным
};
#endif
// myLib.cpp
#include "myLib.h"
void myFunction() { // реализация функции (определение)
// сделай что-нибудь...
}
int mySuperGlobalVariable; // определение
int MyClass::someMethod() { return 2; } // определение метода
// main.cpp
#include <myLib.h>
int main() {
mySuperGlobalVariable = 10;
myFunction();
MyClass instance;
int first = instance.someMethod();
int second = instance.anotherMethod();
}
Не могли бы вы привести пример, как это правильно сделать? Я уверен, что для вас это звучит тривиально, но я с трудом понимаю, что вы сказали., @Cowboy_Patrick
Большое спасибо :) Я пытался объявить и инициализировать его в myLib.cpp и забыл ключевое слово extern в myLib.h., @Cowboy_Patrick
вы можете использовать #pragma Once
вместо старомодного #ifndef _myLib_h_guard_
:p, @Jaromanda X
- Что мне делать с StackOverflow при ошибке компиляции?
- Библиотека не найдена при использовании команды arduino-cli (хотя работает с Arduino IDE)
- Разбить большой файл на более мелкие файлы
- Ошибка компиляции в Ubuntu 18.04
- Проект не компилируется, когда я помещаю функции ниже вызовов функций
- Статус выхода 1 не может скомпилироваться
- Ошибка: expected unqualified-id before 'if'
- Как компилировать, загружать и контролировать через командную строку Linux?
ты неправильно используешь охрану. посмотрите какую-нибудь библиотеку для правильного использования и используйте файлы .h, @Juraj