atmel studio ifndef 编译错误

atmel studio ifndef compilation error

您好,imy 项目识别不存在的变量的双重定义 2 次。我想有些方法通过更改我的代码并重新编译它会卡住。

LedMatrix7219.cpp.o:(.data.Alphaletter+0x0): multiple definition of `Alphaletter' LedController.cpp.o:(.data.Alphaletter+0x0): first defined here

LedMatrix7219.cpp.o:In function `loop' LedController.cpp.o:(.bss.arr+0x0): first defined here

LedMatrix7219.cpp.o:In function `loop' LedController.cpp.o:(.data.Alphaletter2+0x0): first defined here

collect2.exe*:error: ld returned 1 exit status

我有一个 class LedController 和一个 header LettersDefinition.h

所有 header 都是这样开始的:

我正在从 LetterDefinition.h 到 LedController 包括一个结构和一个枚举,所以在 header 我需要包括 LetterDefinition.h 才能产生一定的影响。

#ifndef __LEDCONTROLLER_H__
#define __LEDCONTROLLER_H__

#include <Arduino.h>
#include "LettersDefinition.h"

LetterStruct finalText;
String theText="Test";

void test();
//it does some extra staff
#endif //__LEDCONTROLLER_H__

和字母定义的header。

#ifndef LETTERSDEFINITION_H_
#define LETTERSDEFINITION_H_

#include "arduino.h"
#include <avr/pgmspace.h>

struct LetterStruct{

    lettersEnum name;
    uint8_t size;
    uint8_t columnSize[5];
    uint8_t data[18];
}Alphaletter;
#endif /* LETTERSDEFINITION_H_ */

然后从我的主 .ide 文件调用 Ledcontroller 的测试函数,我得到了上面看到的错误。测试功能仅检查 LetterStruct.name 变量。

我的 .ide 是这样的:

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>
#include "LedController.h"   

LedController controller;

void setup()
{
    //irrelevant inits
}

void loop()
{
    controller.test();
    delay(2000);
}

如果我从 LedController.h 中删除了 #include "LettersDefinition.h" ,这个错误将取代 LedController.h 中未定义 LetterStruct 的错误,这是正常的,因为我有添加 LettersDefinition.h 以便定义。

您的问题源于您在 header 个文件中 "define" 个变量。这一般会导致多重定义问题,不是标准设计。

您需要遵循的模型是在源文件中定义一次:

//some.cpp
// this is define
int variableX = 5;

并在header文件中声明:

//some.h
// this is declare
extern int variableX;

包含 header 的所有其他源文件只处理 "extern" 行,大致表示 "there is an int variableX that will exist in the final program"。编译器遍历每个 .cpp .c 文件并创建一个模块。对于定义变量的some.cpp,它会创建变量X。所有其他 .cpp 文件将只有一个 extern 引用,它是一个占位符。链接器在将所有模块组合在一起时将解析这些占位符。

在您的具体情况下,这意味着更改:

// .h file should only be externs:
extern LetterStruct finalText;
extern String theText;

// .cpp file contains definitions
LetterStruct finalText;
String theText="Test";