解决链接器错误:对静态类成员的未定义引用

时间:2011-04-09 05:29:31

标签: c++ arduino static-members

我的代码是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 sketch目录中。 Core.a是已编译的AVR库。

4 个答案:

答案 0 :(得分:11)

您必须在源文件中定义您的类静态。把它们放在课堂上只是声明它们在那里,但仍然需要定义它们。

在您的.cpp文件中,您可以这样做:

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

输入适当的初始值;我只是假设评论是针对构造函数的。

答案 1 :(得分:2)

您需要创建内存并初始化静态变量。

在您的CPP文件中添加以下内容:

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

答案 2 :(得分:2)

因为值_serial是静态的,所以当没有实例化对象时它就存在。 这意味着您必须在代码中将其声明为

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

已经有人建议。

如果您想在init函数中更改它,只需将_serial = ...行更改为SerialServoControl::_serial = NewSoftSerial(tx, rx).即可 当然,这意味着您必须为NewSoftSerial类定义相关的构造函数。

希望这有帮助。

答案 3 :(得分:1)

我知道这有点死了,但在我的情况下,我忘了定义我引用的方法,想象一下.......

是的,他们是DECLARED,但当我检查我的.cpp文件时,没有他们的定义,所以这次错误是字面意思。