【问题标题】:Resolving a linker error: undefined reference to static class members解决链接器错误:对静态类成员的未定义引用
【发布时间】:2011-04-09 05:29:30
【问题描述】:

我的代码是 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 库。

【问题讨论】:

    标签: c++ arduino static-members


    【解决方案1】:

    你必须在源文件的某个地方定义你的类静态。将它们放在类中只是声明它们在那里,但仍然需要定义它们。

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

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

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

    【讨论】:

    • 哇,感谢您的快速响应。作为初始化,我可以在 CPP 文件中轻松地将 _tx 和 _rx 设置为零,但我希望能够将引脚编号从 main() 委托给 _serial 构造函数。我尝试将 _serial 转换为指针并在我的 init() 方法中填充指针,但它没有解决问题。有什么建议么?再次感谢!
    • 您仍然可以拥有init 函数,但您可能还需要NewSoftSerial 上的init 函数。使用指针也应该可以解决您的问题;您必须在 init 函数中创建对象。
    • 啊哈!我相信我现在已经整理好了。再次感谢您的及时帮助。我在 C++ 方面还是有点陌生​​,但我学得很快。我正在上传代码进行测试。
    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

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

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

      这已经被建议了。

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

      希望这会有所帮助。

      【讨论】:

        【解决方案4】:

        我知道这有点死,但就我而言,我忘记定义我引用的方法,想象一下......

        是的,它们已被声明,但是当我检查我的 .cpp 文件时,它们没有定义,所以这次错误是字面的。

        【讨论】:

          猜你喜欢
          • 2014-02-17
          • 2021-07-10
          相关资源
          最近更新 更多