Arduino库:函数的多个定义

时间:2013-06-14 11:47:25

标签: c++ arduino

今天我在尝试使用IRremote库时遇到了一个奇怪的问题,我设法将问题删除如下。如果您在库中有一个文件夹,其中包含Foo.hFoo.cpp,并写一个sketch以包含Foo.h:

foo.h中

#ifndef Foo_H
#define Foo_H

int AAA() {
    return 0;
}

#endif

Foo.cpp中

#include "Foo.h"

草图

#include <Foo.h>

void setup(){

}

void loop(){

}

错误消息是:

 Foo\Foo.cpp.o: In function `AAA()':

 E:\workShop\Arduino\libraries\Foo\/Foo.h:5: multiple definition of `AAA()'

 includeTest.cpp.o:E:\workShop\Arduino\libraries\Foo/Foo.h:5:

 first defined here

我正在使用Windows 7 32位计算机。在Arduino 1.0.5,1.0.4和21,22上测试。


因此,通过一些研究,我发现问题来自于我对预处理器和链接的混淆。这个问题解释了预处理器如何包含文件并包含guard:

以下是帮助我理解链接的一些页面:

这是对内联说明符的更好解释:

4 个答案:

答案 0 :(得分:11)

好吧,你已经在两个地方定义了这个函数:一次在Foo.cpp中,它包含标题,再次在你的草图中包含标题。 C和C ++标头不提供模块系统,只是简单地粘贴它们来代替include语句。

在标头中声明 AAA,但在Foo.cpp中定义(因此只有一个定义),或标记为{{1} }。

答案 1 :(得分:5)

好吧,至少可以说,你文件中的东西分布是不寻常的。

以下是通常的做法:

foo.h中

#ifndef Foo_H
#define Foo_H

int AAA(void);  // Just the prototype, not the function body

#endif

Foo.cpp中

#include "Foo.h"   // include the h file, although not strictly neecessary

// make the function and body
int AAA(void)
{
    return 0; 
}

Sketch.cpp

#include <Foo.h>  // include prototype, so the AAA function becomes known

void setup()
{
     ...
     AAA();   // call AAA somewhere
}

void loop(){

}

答案 2 :(得分:1)

您可以在标头中定义该功能,因此您应该使用inline关键字:

inline int AAA(){return 0;}
//               ^^^^^^^^^^ definition

或者,只将标题中的声明和实现.cpp文件中的定义放在一起进行编译。

foo.h中

#ifndef Foo_H
#define Foo_H

int AAA();

#endif

Foo.cpp中

#include "Foo.h"

int AAA(){return 0;}

答案 3 :(得分:0)

如果你的程序结构稍微复杂一点,它比Bbrado的答案要复杂一点。您需要#include <Arduino.h>和#include帮助文件,如下所示:

testCall.ino

#include "testCall.h"
void setup() {
  AAA();
}
void loop() {
}

testCall.cpp

#include "testCall.h"
beeHive AAA(void){
    beeHive a;
    a.bee = (byte)1;
    a.hive = (byte) 2;
    return a;
}

testCall.h

#include <Arduino.h>
struct beeHive {
  byte bee;
  byte hive;
};
beeHive AAA (void); //  prototype only