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

发布于 2024-10-31 07:29:35 字数 2819 浏览 0 评论 0原文

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

My code is Arduinoish. I turned on verbose compiling so I could verify that all the .o files are indeed getting passed to the linker correctly, and they are (linker command below). This leads me to believe that it is some sort of syntax error.

Googling for the error "undefined reference to in function" produces a lot of results with answers like "add foo.o to your linker command like so", etc.

I hope the solution is as simple as a missing dot or -> somewhere.

I'm getting this series of errors in one file, from the linker:

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'

The .h file:

#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

and the .cpp file:

#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

The linker command (I've removed the explicit temporary directory paths that the IDE generates for clarity and broken it out to multiple lines. The actual command is explicit as to the location of all these files):

  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

All of these files (SerialServoControl, Wheel_Chair_Joystick, NewSoftSerial, WheelChairMotor) exist in the Arduino sketch directory. Core.a is the compiled AVR library.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

心在旅行 2024-11-07 07:29:35

您必须在源文件中的某个位置定义类静态。将它们放入类中只是声明它们在那里,但仍然需要一些东西来定义它们。

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

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

放置适当的初始值;我只是假设注释是针对构造函数的。

You have to define your class statics in a source file some where. Putting them in the class just declares that they are there, but something still needs to define them.

Inside your .cpp file your can do so like this:

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

Put appropriate initial values; I just assumed the comment was for the constructor.

黯然 2024-11-07 07:29:35

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

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

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

You need to create memory and initialize your static variables.

In your CPP file add the following:

NewSoftSerial SerialServoControl::_serial(9, 8);
char SerialServoControl::_tx = 0;
char SerialServoControl::_rx = 0;
℡寂寞咖啡 2024-11-07 07:29:35

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

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

已经建议的那样。

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

希望这有帮助。

Because the value _serial is static, it exists when an object isn't instantiated.
This means that you must declare it in the code as

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

which has already been suggested.

If you then want to change it in the init function, you simply have to change your _serial = ... line to SerialServoControl::_serial = NewSoftSerial(tx, rx).
Of course, this means you'll have to define a relevant constructor for the NewSoftSerial class.

Hope this helps.

∞琼窗梦回ˉ 2024-11-07 07:29:35

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

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

I know this is somewhat dead, but in my case I forgot to define the methods I was referencing, imagine that.......

Yes they were DECLARED, but when I checked my .cpp file, there was no definition for them, so this time the error was literal.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文