A la compilation, j'obtiens les messages d'erreur suivants :
Arduino : 1.6.7 (Windows XP), Carte : "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"
C:\Documents and Settings\Pierre\Mes documents\Arduino\Test_01\Test_01.ino: In function 'void setup()':
Test_01:6: error: invalid use of incomplete type 'class UneClasse'
maClasse.faire();
^
Test_01:3: error: forward declaration of 'class UneClasse'
extern class UneClasse maClasse;
^
exit status 1
invalid use of incomplete type 'class UneClasse'
J'avoue que je ne sais pas interpréter ces messages et en déduire ce qui ne va pas.
si je ne dis pas de bétises (mais il est fort probable que j'en dise) l'IDE arduino avant d'envoyer le fichier ino au compilateur l'analyse et crée un .h automatiquement généré avec toutes les déclarations utiles. Mais il ne le fait que pour le .ino, si tu as des fichiers .cpp en plus, il faut le faire manuellement, comme avec le .h d'une librairie : tu met les prototypes de tes classes dans le fichier.h, tu inclus avec #include "ton_truc.h" et ça fonctionne, sans besoin d'utiliser "extern" autant que je sache.
Il faut que tu définisses ta classe dans un fichier .h et que tu l'inclues dans ton fichier .ino et dans ton fichier .cpp
La déclaration que tu utilises est une déclaration partielle de la classe. Elle est en général utilisée quand on définit un pointeur sur cette classe dans une autre classe et qu'on ne veut pas inclure la définition de classe entière.
Mais pour utiliser la classe (par exemple appel des fonctions membres), il faut que le compilateur connaisse la définition complète de la classe, donc il faut inclure la définition complète.
Pour continuer les infos de Bricofoy et de Kamill ce qui est envoyé au compilateur est un vrai fichier C/C++
Pour ce faire l'IDE réalise un certain nombre d'actions sans le dire mais uniquement sur le fichier ino:
Prédéclaration de toutes les fonctions dont bien entendu setup() et loop()
Création de la fonction obligatoire main()
La structure du fichier qui est envoyé au compilateur est (en gros) :
reprise de la liste des #include
reprise de la liste de déclaration de variables utilisateur
Ajout des déclarations des fonctions setup(), loop() plus toutes les fonctions utilisateur comprises dans le fichier ino
// création fichier main
void main()
{
init(); // Configuration des registres du micro pour le mode Arduino (Timers, config ADC, config UART, etc.....)
setup();
for( ; ; ) // --> création de la boucle infinie
{
loop();
}
}
C'est un peu dommage que cette information ne soit pas plus voyante sur le site Arduino. A trop vouloir simplifier la tâche des débutants on oublie l'essentiel qui intéresse les non débutants.
kamill:
... Il faut que tu définisses ta classe dans un fichier .h et que tu l'inclues dans ton fichier .ino et dans ton fichier .cpp ...
Ça revient donc à faire une bibliothèque classique. Je pensais que la structure de fichier joint permettait de s'en passer.
kamill:
... La déclaration que tu utilises est une déclaration partielle de la classe ...
C'est là où je ne comprends pas. En quoi est-elle partielle ? Je la pensais complète dans le sens où, lorsque je met le même code dans le fichier.ino, tout fonctionne.
ChPr:
C'est là où je ne comprends pas. En quoi est-elle partielle ? Je la pensais complète dans le sens où, lorsque je met le même code dans le fichier.ino, tout fonctionne.
La déclaration 'extern class UneClasse maClasse;' est partielle car elle ne défini pas complètement la classe UneClasse et par là ne déclare pas non plus complètement la variable maClasse.
Ca ne fonctionne pas non plus dans un fichier .ino. Essaies le code suivant pour t'en convaincre.
En C/C++ extern ne veut pas forcément dire que la définition est externe au fichier, mais que la définition n'est pas connue au moment de la déclaration. Elle peut être définie plus loin dans le fichier.
kamill:
En C/C++ extern ne veut pas forcément dire que la définition est externe au fichier, mais que la définition n'est pas connue au moment de la déclaration. Elle peut être définie plus loin dans le fichier.
Je peux avoir un petit exemple d'application dans un fichier unique ?
extern int toto;
void setup() {
toto=0;
}
int toto;
void loop() {
toto++;
}
C'est rarement utilisé pour des variables simples.
Ca présente plus d'intérêt si on a gros tableau de constantes qu'on veut reléguer à la fin du fichier pour améliorer la lisibilité du source.
J'ai utilisé Pascal que de manière superficielle, donc je ne saurais dire si forward et externes sont équivalents.
Mais en C/C++ le type de la variable doit être complètement défini avant son utilisation.
Tu pourrais donc faire
extern class Tutu danse;
// définition de la class Tutu avant son utilisation
class Tutu {
public:
Tutu() {};
void tourner() {};
};
void setup() {
danse.tourner();
}
void loop() {
}