Ошибка: «undefined reference to ...» при вызове функций непустого класса изнутри класса

Раньше я не использовал Arduino для чего-либо столь сложного, как этот проект (пока что это были проекты с одним скетчем), и теперь, когда я создаю собственные библиотеки для проекта, у меня возникли трудности с компиляцией кода.

Я вижу, что именно методы класса, которые что-то возвращают, вызывают проблему, а те, которые напрямую редактируют переменные класса, похоже, не вызывают проблем при компиляции (т. е. функции void).

Я не могу поделиться самим кодом, но вот измененная и урезанная версия, которая демонстрирует ту же проблему.

Набросок:

//Issues.ino

#include "CmdLib.cpp"

void setup() {
  //Настройка USB
  Serial.begin(19200);
  Serial.flush();

  //Настройка Bluetooth
  Serial0.begin(9600);
  Serial0.flush();
}

void loop(){
  CheckForPCMessages();       // Анализирует все сообщения с USB и Bluetooth
  //Все остальные вещи, которые нам нужно сделать
}

void CheckForPCMessages(){
  CheckForMessages(&Serial);  //Сначала проверьте USB
  CheckForMessages(&Serial0); //Затем проверяем Bluetooth
}

template <class T> void CheckForMessages(T *port){
  //Используем шаблон функции, который работает для USB и аппаратного последовательного порта
  if(port->available() != 0){
    String received_string = port->readStringUntil('\n');
    port->flush();
    Serial.print(received_string);
    Serial.println(" was received.");
    Command received_cmd(received_string);
    //Выполнить какие-либо действия с командой (добавить ее к Q и т. д. и т. п.)
  }
}

Заголовок:

//CmdLib.h

#ifndef CmdLib_h
#define CmdLib_h

#include "Arduino.h"

enum CommandLabel{
  //Не команда
  NO_COMMAND = 0,

  //...
  //Еще куча других вариантов, которыми я не могу поделиться
  //...
};

enum CommandType{
  NA = 0,  
  //...
  //Еще куча других вариантов, которыми я не могу поделиться
  //...
};

class Command{
  public:
    Command(String msg);
    String GetCmdStringFromMessageString(String full_string);
    CommandLabel GetLabelFromString(String labelstr);
    void SetLabelAndType(String labelstr);
    void SetLabel(CommandLabel label);
    void SetType(CommandLabel label);

  private:
    String _x = "";
    String _y = "";
    String _z = "";
    CommandLabel _label = NO_COMMAND;
    CommandType _type = NA;
};

#endif

Файл cpp:

//CmdLib.cpp

#include "CmdLib.h"

Command::Command(String msg){
  String labelstr = Command::GetCmdStringFromMessageString(msg); //Отделяет метку от сообщения
  Command::SetLabelAndType(labelstr); // Устанавливает переменные _label и _type
}

String GetCmdStringFromMessageString(String full_string){
  //Вытаскивает все до первой запятой
  int first_comma = full_string.indexOf(',');
  String output;
  if(first_comma != -1){
    output = full_string.substring(0,first_comma);
  }
  else{
    output = full_string;
  }
  return output;
}

void Command::SetLabelAndType(String labelstr){
  CommandLabel label = GetLabelFromString(labelstr);  //Получить метку из строки
  Command::SetLabel(label);                           //Установить метку
  Command::SetType(label);                            //Установить тип на основе метки
}

CommandLabel GetLabelFromString(String labelstr){
  //...
  //Умение определять, что возвращать...
  //...
  return NO_COMMAND;
}

void Command::SetLabel(CommandLabel label = NO_COMMAND){
  _label = label;
}

void Command::SetType(CommandLabel label){    //Установить _type на соответствующий тип на основе метки
  //...
  //Умение определять, что возвращать...
  //...
  _type = NA;
  return;
}

И вот ошибка:

sketch\CmdLib.cpp.o: В функции `Command::SetLabelAndType(String)':

[УДАЛЕНО]/temp/arduino_build_557572/sketch/cmdlib.cpp:24: неопределенная ссылка на `Command::GetLabelFromString(String)'

sketch\CmdLib.cpp.o: В функции `Command::Command(String)':

[УДАЛЕНО]/temp/arduino_build_557572/sketch/cmdlib.cpp:6: неопределенная ссылка на `Command::GetCmdStringFromMessageString(String)'

collect2.exe: ошибка: ld вернул статус выхода 255

выходной статус 255 Ошибка компиляции для платы Fubarino Mini.

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

Любая помощь будет высоко оценена.

, 👍1


1 ответ


Лучший ответ:

1

Вы забыли поместить функцию в класс:

CommandLabel GetLabelFromString(String labelstr){

должно быть:

CommandLabel Command::GetLabelFromString(String labelstr) {

Кроме того, если вам необходимо использовать объекты String (ужас!), то пожалуйста передавайте их как ссылку, чтобы избежать ненужного выделения памяти в куче и копирования данных:

CommandLabel Command::GetLabelFromString(String &labelstr) {
,