I am making a tiny game, and want to store high-scores. I made a Highscore-class in the top of the sketch file, like this:
class Highscore {
public:
String name;
int score;
String toString() {
return this->name + " - " + (String)score;
}
Highscore(String name, int score) {
this->name = name;
this->score = score;
}
};
setup() { // etc
Now. Near the bottom of the sketch, I have a function I want to take a Highscore-object as a parameter, but the compiler will not let me. Example:
void writeHighscore(Highscore hs) {
File f = SD.open("high.txt", FILE_WRITE);
// Do stuff
The complation error is as follows:
sketch.ino:19:21: error: variable or field ‘writeHighscore’ declared void
sketch.ino:19:21: error: ‘Highscore’ was not declared in this scope
sketch.ino: In function ‘void setup()’:
sketch.ino:64:20: error: ‘writeHighscore’ was not declared in this scope
After changing parameter type to String, int or whatever, all the errors go away. I am able to create Highscore-objects INSIDE the writeHighscore()
function, but how can I pass objects to it?
Edit 1 - Object creation
Highscore hs = Highscore("John", 975);
Serial.println(hs.toString()); // Prints "John - 975" as expected
writeHighscore(hs); // Error
2 Answers 2
You are doing everything right, but you need to move the class outside of your .ino file for this to work. (削除) I'm not sure why the arduino IDE makes you do this (削除ここまで) (see edit) , but it is something I've run into before.
I just tested this, and moving the class declaration outside the ino and into a header file in the project folder makes it compile correctly. Just remember to include the header you make in the ino and to #include "Arduino.h"
in the header to get access to "String" again.
Technically, only a forward declaration of the class needs to be in a different file.
Edit:
I'm relatively sure what is happening is the IDE is generating forward declarations for all your functions but not the class, which are placed before your class definition. This means that breaking the function regex the IDE uses with a dummy "throw()" fixes your problem. for example:
void writeHighscore(Highscore hs) throw() { ...
should work just fine (it worked for me)
This is a classic example of the IDE "helping" you by generating function prototypes, and not doing it very well. Example code to reproduce:
class Highscore {
public:
String name;
int score;
String toString() {
return this->name + " - " + (String)score;
}
Highscore(String name, int score) {
this->name = name;
this->score = score;
}
};
void setup () { }
void loop () { }
void writeHighscore(Highscore hs)
{
// do stuff
}
This gives the error:
sketch_jul06b:4: error: variable or field ‘writeHighscore’ declared void
sketch_jul06b:4: error: ‘Highscore’ was not declared in this scope
If you look at the output of the IDE preprocessor (you can do this by turning on verbose compilation, and finding out the name of the file it is actually compiling) you see this:
#line 1 "sketch_jul06b.ino"
#include "Arduino.h"
void setup ();
void loop ();
void writeHighscore(Highscore hs);
#line 1
class Highscore {
public:
String name;
int score;
String toString() {
return this->name + " - " + (String)score;
}
Highscore(String name, int score) {
this->name = name;
this->score = score;
}
};
void setup () { }
void loop () { }
void writeHighscore(Highscore hs)
{
// do stuff
}
The important part is that it put:
void writeHighscore(Highscore hs);
before where the class is declared.
You can fix the error by simply generating your own function prototype like this:
void writeHighscore(Highscore hs); // function prototype
void writeHighscore(Highscore hs)
{
// do stuff
}
Now it compiles without errors. It detects your own function prototype, and therefore does not generate its own. The first few lines of the generated file are now:
#line 1 "sketch_jul06b.ino"
#include "Arduino.h"
void setup ();
void loop ();
#line 1
That troubling prototype has gone.
&hs
approach beforee writing the post, as well as passing the pointerwriteHighscore(&hs)
->void writeHighscore(Highscore *hs)
but to no avail.