8
votes

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:

Foo.h

#ifndef Foo_H
#define Foo_H

int AAA() {
    return 0;
}

#endif

Foo.cpp

#include "Foo.h"

Sketch

#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:

And this is a better explanation of inline specifier:

4

4 Answers

13
votes

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.

6
votes

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(){

}
1
votes

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;}
0
votes

It is a little more complicated than Bbrado's answer if the structure of your program is a little more complicated. You need to #include <Arduino.h> and #include the help file as shown here:

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