Utilisation d'une classe définie dans un fichier annexe

Bonjour à toutes et à tous,

J'ai une application Séquenceur.ino définie dans le répertoire Séquenceur. Dans ce répertoire, j'ai aussi un fichier Utilitaires.cpp.

Dans ce fichier, j'ai défini la class Machin et un tableau de Machin tel que :

class Machin {
...
}

Machin machin[2][2];

Je souhaite me servir de la variable machin dans le fichier Séquenceur.ino. Aussi, je déclare :

extern Machin machin;

A la compilation, j'obtiens l'erreur suivante :

error: 'Machin' does not name a type

Comment faire pour utiliser cette classe dans le fichier Séquenceur.ino ?

merci de votre aide.

Pierre

As-tu créé un fichier ".h" contenant la définition de "Machin" ?

Oui, le voici :

# include <Arduino.h>

class Machin {
public:
  ...
};

Machin machin[6][4];

Mais là, quand j'utilise la variable dans le fichier .ino, j'obtiens :

 'machin' was not declared in this scope

J'ai essayé tout un tas de combinaisons, même avec des bibliothèques. Dans ce dernier cas, j'arrive à utiliser la variable dans le fichier .ino, mais pas dans le fichier Utilitaire.

Merci de votre aide.

Pierre

Il faut créer un fichier "Machin.h" avec la définition de la classe, l'inclure dans ton .ino et le machin.cpp.

Je tourne en rond depuis des heures et des heures ...

Voici les fichiers que j'ai créés :

fichier Bidule.ino :

#include <Arduino.h>
#include <Truc.h>

void setup() {
  // put your setup code here, to run once:
  machin[1][1].x = 2;

}

void loop() {
  // put your main code here, to run repeatedly: 
  
}

le fichier Truc.h :

#ifndef Truc_h
#define Truc_h

#include <Arduino.h>

class Machin {
public:
  int x;
  int y;
};

Machin machin[6][4]; // tableau de Machin

#endif

et le fichier Truc.cpp :

#include <Arduino.h>
#include <Truc.h>

void Fct() {
  machin[0][0].y = 5;
}

Je ne m'en sors pas.

Si je mets en commentaire les lignes utilisant machin dans Bidule.ino et Truc.cpp : ça compile.

Dès que j'enlève les commentaires, soit dans le fichier Bidule.ino ou Truc.cpp, j'obtiens l'erreur :

'machin' was not declared in this scope

Voilà, si vous pouviez me dire ce qu'il faut coder pour que je puisse utiliser mon tableau de Machin à la fois dans le fichier Bidule.ino et Truc.cpp ...

Merci de votre aide.

Pierre

Salut,

Reprenons les choses depuis le début.

À en juger par le code que tu nous donnes, tu maitrises déjà cette notion, mais rappelons là malgré tout : Tes classes sont des sortes de moules à instances. En d'autres termes, lorsque tu crée une classe, tu crée effectivement un couple Truc.h / Truc.cpp de sorte à pouvoir créer des instances de Truc. Jusque là, ça va.

La première petite maladresse se situe dans ton Truc.cpp. En effet, tu implémente une méthode (Fct()) sans que celle-ci n'ait été déclarée dans ton Truc.h. Il faut donc la déclarer dans le fichier Truc.h :

#ifndef Truc_h
#define Truc_h

class Machin {
  public:
    void funct();
  private:
    int x;
    int y;
};

#endif

Tu remarqueras également que j'ai modifié la portée de x et y. En POO, la règle veut que seuls les méthodes de la classe soient capables d'accéder aux attributs de ladite classe (mais ça compilera/fonctionnera quand même).

J'ai également enlevé la ligne :

Machin machin[6][4]; // tableau de Machin

Elle n'a rien a faire ici, on y revient un peu plus tard.

Passons maintenant à ton fichier Truc.cpp. Ce fichier est là pour implémenter les méthodes de ta classes. En l'occurrence, ta classe n'a ici qu'une méthode : funct();.

Tout d'abord, il te manque l'opérateur de résolution de portée ( :: ) chargé d'indiquer au compilateur que la méthode appartient à ta classe. Si on corrige ça, ça donne le code suivant :

#include <Truc.h>

void Truc::funct() {
  // ...
}

Reste à implémenter cette méthode, et c'est là qu'il y a une petite boulette.

Au début, je te disais qu'une classe était un moule à instance. Or, dans ton code, tu travailles sur une instance, et non sur le moule. J'arrive pas à faire plus clair, l'exemple devrait parler un peu plus :

#include <Truc.h>

void Truc::funct() {
  this->y = 5; // le mot clé 'this' indique que tu travaille sur l'attribut de la classe, et non sur une instance qui n'existe pas encore
}

Ton code devrait maintenant compiler. Voyons comment utiliser ta classe au sein de ton programme :

#include <Truc.h>

void setup() {
  // on crée une INSTANCE de la CLASSE Truc :
  Truc machin;
  // on appelle la méthode funct() sur l'INSTANCE :
  machin.funct();
}

void loop() {
  // ...
}

Et là, ton attribut y à la valeur 5.

Tu n'as plus qu'à modifier ta méthode pour quelle soit capable de mettre à jour ton attribut en fonction d'un paramètre que tu lui passes :

Truc.h :

// ...
class Machin {
  public:
    void funct(int);
// ...

Truc.cpp :

void Truc::funct(int val) {
  this->y = val; // l'intérêt des setters et de réaliser des tests avant d'assigner la valeur. on assure alors qu'on ne mets pas des valeurs interdites, etc. passons pour l'exemple.
}

Ainsi, dans ton programme :

Bidule.ino :

#include <Truc.h>

void setup() {
  // on crée notre instance :
  Truc machin;
  machin.funct(5);

  // L'attribut 'y' vaut désormais 5.

  machin.funct(42);

  // L'attribut 'y' vaut désormais 42.


  // Exemple avec ton tableau :

  // On crée un tableau de Truc :
  Truc tableauDeTrucs[6][4];

  // On appelle funct() sur l'élément [1][1] :
  tableauDeTrucs[1][1].funct(666);

  // L'attribut 'y' de l'élément [1][1] du tableau de Truc vaut désormais 666.
}

void loop() {
  // ...
}

En espérant avoir été suffisamment clair,
À bientôt,

--
N.

Je te remercie nicolasc_eu pour la peine qe tu t'es donnée pour me mettre les points sur les "i".

Pour autant, je ne pense pas que cela résolve mon problème que j'ai mal expliqué. Quelques éclaircissements :

  • dans Truc.cpp, Fct() est une fonction quelconque, n'appartenant pas à l'objet Machin. Je l'ai mise là uniquement pour pouvoir donner une valeur à l'instance machin[0][0].y
  • Mon objet Machin n'est qu'une structure (je pourrais utiliser struct au lieu de class) me permettant de créer un tableau (bidimensionnel) dans lequel je veux y mettre des valeurs.
  • par ailleurs, je veux ne créer qu'un seul tableau, mais qui soit accessible à la fois dans Bidule.ino et dans Truc.cpp. Truc.cpp n'étant qu'un fichier "utilitaires" où j'implante diverses fonctions pour ne pas surcharger le fichier Bidule.ino

Merci de vottre aide.

NOTA : une chose qui m'a surpris : dans l'exemple que j'ai donné, je pouvais écrire n'importe quoi dans le fichier Truc.h, n'importe quelle erreur de syntaxe, ... le compilateur ne voyait rien ??? (Arduino 1.5.2 ou 1.5.7)

Pierre