I want to store a number of strings in an object. Currently I have:
class MyClass {
int numStrings = 0;
??? strings[20];
public:
void addString(const char str[]);
void print();
};
void MyClass::addString(const char str[]) {
strings[numStrings] = str;
numStrings++;
}
void MyClass::print() {
for (int i = 0 ; i < numStrings ; i++) {
Serial.println(strings[i]);
}
}
Serial.println()
works with strings in RAM and in PROGMEM alike.
Is there a type that I can give to my strings
variable that allows me to store both types of strings?
MyClass s;
s.addString("This should work");
s.addString(F("This should work, too"));
1 Answer 1
Is there a type that I can give to my strings variable that allows me to store both types of strings?
No, but you could tag the pointer or add a vector with type information or ultimately use a class hierarchy (BaseString<-SRAMString, PROMEMString).
As a pointer is 16-bit (Arduino Uno) and there is limited amount of SRAM it is possible to add a magic number to pointers to determine the address space.
Obviously the print() member function will have to use the right type and you will also need a new addString for F() strings. Check how F() is defined.
Cheers!
-
I don't know how to "tag a pointer", but when working with a magic number I would make that a void pointer?AndreKR– AndreKR2017年12月14日 10:14:27 +00:00Commented Dec 14, 2017 at 10:14
-
Here is an example of mapping EEPROM, SRAM and PROGMEM to a single address space: github.com/mikaelpatel/Arduino-Shell/blob/master/Shell.h#L1058Mikael Patel– Mikael Patel2017年12月14日 10:35:21 +00:00Commented Dec 14, 2017 at 10:35
-
1The simplest scheme is to use the sign bit for PROGMEM, i.e. add 0x8000 to PROGMEM pointers.Mikael Patel– Mikael Patel2017年12月14日 10:39:35 +00:00Commented Dec 14, 2017 at 10:39
-
I don't get it. So when I get a
__FlashStringHelper*
I add 0x8000 to mark that it points to PROGMEM. But then I still can't store that in aconst char*
variable, can I?AndreKR– AndreKR2017年12月14日 10:42:05 +00:00Commented Dec 14, 2017 at 10:42 -
Tell the compiler what you want:
uint16_t str = 0x8000U + (uint16_t) str_P; strings[numStrings++] = (const char*) str;
Mikael Patel– Mikael Patel2017年12月14日 11:51:17 +00:00Commented Dec 14, 2017 at 11:51