Today I encountered a weird problem when trying to use IRremote library, and I managed to strip down the problem as following. If you have a folder in libraries, with Foo.h
and Foo.cpp
inside, and write a sketch to include Foo.h:
#ifndef Foo_H
#define Foo_H
int AAA() {
return 0;
}
#endif
#include "Foo.h"
#include <Foo.h>
void setup(){
}
void loop(){
}
The error message is:
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
I'm using a Windows 7 32-bit machine. Tested on Arduino 1.0.5, 1.0.4, and 21, 22.
So with some research I figured out the problem comes from my confusion of preprocessor and linking. This question explains how preprocessor includes file and include guard:
These are some of the pages helped me understand linking:
1.8 — Programs with multiple files
GCC and Make - A Tutorial on how to compile, link and build C/C++ applications
Guide: Multiple sources
And this is a better explanation of inline specifier:
Well, you have defined the function in two places: once in Foo.cpp where it includes the header, and again in your sketch where it includes the header. C and C++ headers don't provide a module system, they're just literally pasted in place of the include statement.
Either declare AAA
in the header, but define it in Foo.cpp (so there's only one definition), or mark it inline
.
Well, the distribution of stuff in your files is more than unusual to say the least.
Here is how it is commonly done:
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(){
}
You define the function in the header, so you should use the inline
keyword:
inline int AAA(){return 0;}
// ^^^^^^^^^^ definition
Alternatively, place only the declaration in the header, and the definition in an implementation .cpp
file, to be compiled.
Foo.h
#ifndef Foo_H
#define Foo_H
int AAA();
#endif
Foo.cpp
#include "Foo.h"
int AAA(){return 0;}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With