Устранение ошибки компоновщика: неопределенная ссылка на статические члены класса

Мой код Arduinoish. Я включил многословную компиляцию, чтобы убедиться, что все файлы.o действительно правильно передаются компоновщику, и это так (команда компоновщика ниже). Это приводит меня к мысли, что это какая-то синтаксическая ошибка.

Поиск в поиске ошибки "неопределенная ссылка на в функции" дает много результатов с ответами типа "добавьте foo.o к вашей команде компоновщика, например" и т. Д.

Я надеюсь, что решение так же просто, как пропущенная точка или -> где-нибудь.

Я получаю эту серию ошибок в одном файле от компоновщика:

SerialServoControl.cpp.o: In function `SerialServoControl::send(int, int)':
SerialServoControl.cpp:31: undefined reference to `SerialServoControl::_serial'
SerialServoControl.cpp:31: undefined reference to `SerialServoControl::_serial'
SerialServoControl.cpp.o: In function `SerialServoControl::init(char, char)':
SerialServoControl.cpp:9: undefined reference to `SerialServoControl::_tx'
SerialServoControl.cpp:10: undefined reference to `SerialServoControl::_rx'

Файл.h:

#ifndef SERIALSERVOCONTROL_H
#define SERIALSERVOCONTROL_H

#include "NewSoftSerial.h"

class SerialServoControl {
    public:
          //                             rx, tx
          static NewSoftSerial _serial;//(9, 8);

          int _servo_id;
          static char _tx;
          static char _rx;

          static void init(char tx, char rx);
          static void send(int servo_id, int angle);
          void setup(int servo_id);
          void set(int spot);
};

#endif

и файл.cpp:

#ifndef SERIALSERVOCONTROL_CPP
#define SERIALSERVOCONTROL_CPP

#include "WProgram.h"
#include "SerialServoControl.h"

//static
void SerialServoControl::init(char tx, char rx){
    _tx = tx;
    _rx = rx;
    _serial = NewSoftSerial(rx, tx);
    _serial.begin(9600);
}

//static
void SerialServoControl::send(int servo_id, int angle){
    unsigned char buff[6];

    int temp     = angle & 0x1f80;
    char pos_hi  = temp >> 7;
    char pos_low = angle & 0x7f;

    buff[0] = 0x80;        // start byte
    buff[1] = 0x01;        // device id
    buff[2] = 0x04;        // command number
    buff[3] = servo_id;       // servo number
    buff[4] = pos_hi;      // data1
    buff[5] = pos_low;     // data2

    for(int i=0; i<6; i++){
        _serial.print(buff[i], BYTE);

    }
}


void SerialServoControl::setup(int servo_id){
    _servo_id = servo_id;
}

void SerialServoControl::set(int angle){
    SerialServoControl::send(_servo_id, angle);
}

#endif

Команда компоновщика (я удалил явные временные пути к каталогам, которые IDE генерирует для ясности и разбил его на несколько строк. Фактическая команда явно указывает расположение всех этих файлов):

  avr-gcc -Os -Wl,--gc-sections -mmcu=atmega328p \
  -o Wheel_Chair_Joystick_Control.cpp.elf \
  SerialServoControl.cpp.o \
  Wheel_Chair_Joystick_Control.cpp.o \
  WheelChairMotor.cpp.o \
  NewSoftSerial.cpp.o \
  core.a \
  -Lbuild277668752723095706.tmp \
  -lm

Все эти файлы (SerialServoControl, Wheel_Chair_Joystick, NewSoftSerial, WheelChairMotor) существуют в каталоге эскизов Arduino. Core.a это скомпилированная библиотека AVR.

4 ответа

Решение

Вы должны определить статику своего класса в исходном файле. Помещение их в класс просто объявляет, что они есть, но что-то еще должно определить их.

Внутри вашего .cpp подать ваш можно сделать так:

NewSoftSerial SerialServoControl::_serial(9, 8);
char SerialServoControl::_tx = 0;
char SerialServoControl::_rx = 0;

Поставьте соответствующие начальные значения; Я просто предположил, что комментарий был для конструктора.

Вам нужно создать память и инициализировать ваши статические переменные.

В вашем файле CPP добавьте следующее:

NewSoftSerial SerialServoControl::_serial(9, 8);
char SerialServoControl::_tx = 0;
char SerialServoControl::_rx = 0;

Поскольку значение _serial является статическим, оно существует, когда объект не создан. Это означает, что вы должны объявить это в коде как

NewSoftSerial SerialServoControl::_serial(9, 8);
char SerialServoControl::_tx = 0;
char SerialServoControl::_rx = 0;

который уже был предложен.

Если вы хотите изменить его в функции инициализации, просто измените _serial = ... линия к SerialServoControl::_serial = NewSoftSerial(tx, rx).Конечно, это означает, что вам нужно определить соответствующий конструктор для класса NewSoftSerial.

Надеюсь это поможет.

Я знаю, что это несколько мертво, но в моем случае я забыл определить методы, на которые ссылался, представьте, что.......

Да, они были ЗАЯВЛЕНЫ, но когда я проверил свой файл.cpp, для них не было определения, поэтому на этот раз ошибка была буквальной.

Другие вопросы по тегам