Comments 8
Для GCC вы можете делать как-то так:
#include <iostream>
#define PROGMEM
template <char... String>
struct ProgmemString {
static const char PROGMEM v[sizeof...( String ) + 1];
};
template <char... String>
const char ProgmemString<String...>::v[sizeof...( String ) + 1] = {String..., '\0'};
template <typename CharT, CharT... String>
constexpr auto operator"" _progmem()
{
return ProgmemString<String...>::v;
}
int main()
{
std::cout << "progmem string"_progmem << std::endl;
}
+3
Гм. Может быть я не проник в суть статьи или отстал от жизни, но я все-таки не совсем понял, чем не устроил вариант
Собственно, я всегда примерно так и делал. Более того, это рекомендуемый в документации на avr-libc способ решения подобных проблем. Собственно все еще проще:
и, собственно, все.
extern const char PROGMEM caption1[];
const char caption1[] = "Hello";
const char *pStr = caption1;
Собственно, я всегда примерно так и делал. Более того, это рекомендуемый в документации на avr-libc способ решения подобных проблем. Собственно все еще проще:
const char foo[] PROGMEM = "Hello, world!";
...
strcpy_P(dest,foo);
и, собственно, все.
+1
Согласен, этот способ работает, но требуется написать две строки вместо одной.
Плюс сама строка располагается непосредственно в месте ее использования. Ваш пример сложно будет читать, если эти две строки не будут помещаться в экран.
Плюс не требуется придумывать имена для переменных, хранящих строку, что является лишним трудом.
Короче, лень — двигатель прогресса.
Кстати, рекомендуемый в документации способ, не работал одно время. Компилятор ругался, что __attribute__((__progmem__)) не может быть использован при создании переменной, а только в объявлении. Это было давно, но именно оттуда у меня привычка писать отдельно объявление, а потом инициализацию.
strcpy_P(dest,SPS("Hello world!"));
Плюс сама строка располагается непосредственно в месте ее использования. Ваш пример сложно будет читать, если эти две строки не будут помещаться в экран.
Плюс не требуется придумывать имена для переменных, хранящих строку, что является лишним трудом.
Короче, лень — двигатель прогресса.
Кстати, рекомендуемый в документации способ, не работал одно время. Компилятор ругался, что __attribute__((__progmem__)) не может быть использован при создании переменной, а только в объявлении. Это было давно, но именно оттуда у меня привычка писать отдельно объявление, а потом инициализацию.
+1
Понял.
В сущности, разделение объявления строки и места ее использования можно считать фичей. Такой подход позволяет вынести сообщения в отдельный файл, и при необходимости локализации править только его. С именами особой проблемы тоже нет:
Но, конечно, тут на вкус и цвет.
Плюс сама строка располагается непосредственно в месте ее использования.
В сущности, разделение объявления строки и места ее использования можно считать фичей. Такой подход позволяет вынести сообщения в отдельный файл, и при необходимости локализации править только его. С именами особой проблемы тоже нет:
const char init_error_message[] PROGMEM = "Initialization failed.";
const char init_OK_message[] PROGMEM = "Hardware initialized.";
...
Но, конечно, тут на вкус и цвет.
0
Взял библиотеку уже готовую — например adafruit fona.
Там повсеместно используется конструкция
«какой-то текст» располагается во флэш.
Реализацию не сложно посмотреть.
Хотя может и не понял глубины мысли в этом посте.
Там повсеместно используется конструкция
имя_функции(F("какой-то текст"));
«какой-то текст» располагается во флэш.
Реализацию не сложно посмотреть.
Хотя может и не понял глубины мысли в этом посте.
+1
Тоже не понял глубину мысли. Все строки у меня PROGMEM или PSTR, т.е. в flash памяти кода. И все две функции работы со строками немного изменены и это «понимают». Ну нельзя просто так взять конкретный символ и что? pgm_read_byte( (char*)(&(str))+i ) — вот макрос для взятия символа. Ну разве что макросы — зло, а двухстраничные темплейты — добро.
0
Макрос F() — это аналог PSTR.
Весь смысл в том, что эти макросы не работают вне функций. А нам нужно было инициализировать глобальные переменные в кодовой памяти указателями на строку.
Естественно, мы делали так же, как указал LampTester, но нам было лень постоянно так делать и мы нашли такой способ.
Весь смысл в том, что эти макросы не работают вне функций. А нам нужно было инициализировать глобальные переменные в кодовой памяти указателями на строку.
static const char *pStr = PSTR("Hello");
// error: statement-expressions are not allowed outside functions nor in template-argument lists
Естественно, мы делали так же, как указал LampTester, но нам было лень постоянно так делать и мы нашли такой способ.
0
Sign up to leave a comment.
Строки в кодовой памяти AVR