今天我在尝试使用IRremote库时遇到了一个奇怪的问题,我设法解决了以下问题.如果你在库中有一个文件夹,包含Foo.h和Foo.cpp在里面,并写一个草图来包含Foo.h:
#ifndef Foo_H
#define Foo_H
int AAA() {
return 0;
}
#endif
Run Code Online (Sandbox Code Playgroud)
#include "Foo.h"
Run Code Online (Sandbox Code Playgroud)
#include <Foo.h>
void setup(){
}
void loop(){
}
Run Code Online (Sandbox Code Playgroud)
错误消息是:
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
Run Code Online (Sandbox Code Playgroud)
我正在使用Windows 7 32位机器.在Arduino 1.0.5,1.0.4和21,22上测试.
因此,通过一些研究,我发现问题来自于我对预处理器和链接的混淆.这个问题解释了预处理器如何包含文件和包含防护:
以下是帮助我理解链接的一些页面:
这是对内联说明符的更好解释:
Use*_*ess 11
好吧,你已经在两个地方定义了这个函数:一次在Foo.cpp中,它包含标题,再次在你的草图中包含标题.C和C++头文件不提供模块系统,它们只是字面上粘贴代替include语句.
要么在标题中声明 AAA,要在Foo.cpp中定义它(因此只有一个定义),或者标记它inline.
小智 5
好吧,至少可以说,你文件中的东西分布是不寻常的.
以下是通常的做法:
foo.h中
#ifndef Foo_H
#define Foo_H
int AAA(void); // Just the prototype, not the function body
#endif
Run Code Online (Sandbox Code Playgroud)
Foo.cpp中
#include "Foo.h" // include the h file, although not strictly neecessary
// make the function and body
int AAA(void)
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Sketch.cpp
#include <Foo.h> // include prototype, so the AAA function becomes known
void setup()
{
...
AAA(); // call AAA somewhere
}
void loop(){
}
Run Code Online (Sandbox Code Playgroud)