Arduino bibliothèque: plusieurs définitions de fonction
Aujourd'hui, j'ai rencontré un problème bizarre lors de l'utilisation de IRremote bibliothèque, et j'ai réussi à démonter le problème de la manière suivante. Si vous avez un dossier dans les bibliothèques, avec Foo.h
et Foo.cpp
à l'intérieur, et écrire une esquisse d'inclure des Foo.h:
Foo.h
#ifndef Foo_H
#define Foo_H
int AAA() {
return 0;
}
#endif
Foo.cpp
#include "Foo.h"
Esquisse
#include <Foo.h>
void setup(){
}
void loop(){
}
Le message d'erreur est:
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
Je suis sur un Windows 7 32 bits de la machine. Testé sur un Arduino 1.0.5, 1.0.4, et 21, 22.
Ainsi, avec un peu de recherche, j'ai trouvé le problème vient de ma confusion de préprocesseur et de liaison. Cette question explique comment préprocesseur inclut le fichier et comprennent garde:
Ces quelques pages m'ont aidé à comprendre la liaison:
- 1.8 — Programmes avec plusieurs fichiers
- CGC et de Faire Un Tutoriel sur la façon de compiler, de lien et de construire des applications C/C++
- Guide: de Multiples sources
Et c'est une meilleure explication de inline rédacteur de devis:
OriginalL'auteur Xun Yang | 2013-06-14
Vous devez vous connecter pour publier un commentaire.
Bien, vous ont défini la fonction à deux endroits: une fois dans Foo.cpp où il comprend l'en-tête, et de nouveau dans votre croquis, où il comprend l'en-tête. Le C et le C++ en-têtes de ne pas fournir un système de modules, ils sont littéralement collé à la place de l'instruction include.
Soit déclarer
AAA
dans la tête, mais définir dans Foo.cpp (donc il y a une seule définition), ou de la marquerinline
.#ifndef Foo_H
a été la prévention des trucs d'être défini plusieurs fois. Et n'était-ce pas inline censé être utilisé pour améliorer les performances?déclaration != définition
change le lien pour faire face avec des fonctions qui sont définies en-ligne. En termes de performances, il est vraiment seulement un indice pour les compilateurs modernes de toute façon, je ne voudrais pas considèrent généralement une optimisation plus.
Ce conseil n'est pas l'histoire complète. mot-clé inline n'a rien à voir avec le fait que la fonction est définie dans un en-tête. inline est un indicateur pour le compilateur que vous le voulez encore découper le corps de la fonction et de l'insérer dans le lieu où cette fonction est appelée. inline sera la cause de l'appel de la fonction et de retour d'être éliminé. Cela permet de gagner du temps d'exécution pour pousser les paramètres et éclater les valeurs de retour, mais peut augmenter votre taille de code. Chaque lieu, une fonction est appelée, sera remplacé par une copie de l'intégralité de la fonction de code.
qui n'est certainement pas correcte. est dans le cas, mais les compilateurs ne sont pas tenus de fonction inline appelle juste parce que vous utilisez le
inline
mot-clé, et sont parfaitement en mesure de l'inclure des appels, même sans elle.OriginalL'auteur Useless
Même, la distribution des trucs dans vos fichiers est pour le moins inhabituel pour dire le moins.
Ici est de savoir comment il est fait couramment:
Foo.h
Foo.cpp
Sketch.cpp
OriginalL'auteur Bbrado
Vous définissez la fonction dans l'en-tête, de sorte que vous devriez utiliser le
inline
mot-clé:Sinon, placez uniquement la déclaration dans l'en-tête, et la définition de la mise en œuvre
.cpp
fichier à compiler.Foo.h
Foo.cpp
OriginalL'auteur juanchopanza
Il est un peu plus compliqué que Bbrado de réponse si la structure de votre programme est un peu plus compliqué. Vous devez #include
<Arduino.h>
et #inclure le fichier d'aide, comme indiqué ici:testCall.ino
testCall.cpp
testCall.h
OriginalL'auteur Lucky Larry