Други, как в конструктор передать PROGMEM константу?
- Войдите на сайт для отправки комментариев
Сб, 22/02/2020 - 19:47
Так – нет эффекта:
class A
{
public:
const PROGMEM char* text;
};
A a{"Hello World!"};
Так – ошибка, что нельзя так делать:
A a{PSTR("Hello World!")};
Так – не хочу, ибо нужно именно в конструктор совать данные:
A a;
a.text = PSTR("Hello World!");
В конструктор передать так же как в и любую другую функцию. Правда в попытках конструктора нет совсем, так что непонятно что же всё-таки хотелось.
Так – нет эффекта:
А Какого эффекта Вы хотели получить от этой куйни?
Здравствуй жопа-новый-год. Если что то полезное с progmem и классом то #297 eeprom_Ref.h шаблон
classpRef.Так – нет эффекта:
class A { public: const PROGMEM char* text; }; A a{"Hello World!"};Так – ошибка, что нельзя так делать:
A a{PSTR("Hello World!")};Так – не хочу, ибо нужно именно в конструктор совать данные:
A a; a.text = PSTR("Hello World!");То, что у Вас написано является бредом, причём таким, который не позволяет понять, а что же Вы собственно хотели сделать. И кстати, конструктора в Вашем коде нет от слова совсем.
Попробуйте описать словами, значение которых Вы точно понимаете (не использую никаких других слов), что Вы хотите сделать.
То, что у Вас написано является бредом, причём таким, который не позволяет понять, а что же Вы собственно хотели сделать. И кстати, конструктора в Вашем коде нет от слова совсем.
Попробуйте описать словами, значение которых Вы точно понимаете (не использую никаких других слов), что Вы хотите сделать.
где конкретно у меня бред? конструктор в данном примере - дефолтный.
Так – нет эффекта:
А Какого эффекта Вы хотели получить от этой куйни?
экономии RAM на 10 байт, очевидно.
Фермер затеял опасную игру, накинув на вентилятор лопату навоза.
В конструктор передать так же как в и любую другую функцию. Правда в попытках конструктора нет совсем, так что непонятно что же всё-таки хотелось.
У любого класса есть конструктор. Он либо написанный, либо по умолчанию. Нафига мне его писать в примитивном примере, когда можно сразу проинициализировать все свойства класса, без конструктора.
Здравствуй жопа-новый-год. Если что то полезное с progmem и классом то #297 eeprom_Ref.h шаблон
classpRef.пардон, не понял, а при чем здесь eeprom??? здесь речь про флэш память.
Здесь.
//pRef.h----------------------------- #include <avr/pgmspace.h> template <typename T> class pRef { protected: const T* pointer; T get(); public: ~pRef(); pRef() = delete; pRef(const T* a); pRef(const pRef& other) = delete; pRef(pRef&& other); pRef& operator=(const pRef& other) = delete; pRef& operator=(pRef&& other); // operator T(); pRef operator[] (const int index); }; //pRef.cpp----------------------------- /*uint8_t*/ template <> uint8_t pRef<uint8_t>::get() { return pgm_read_byte(pointer); } /* int */ template <> int pRef<int>::get() { return pgm_read_word((uint16_t*)pointer); } /* uint16_t*/ template <> uint16_t pRef<uint16_t>::get() { return pgm_read_word(pointer); } /* uint32_t*/ template <> uint32_t pRef<uint32_t>::get() { return pgm_read_dword(pointer); } /* float*/ template <> float pRef<float>::get() { return pgm_read_float(pointer); } /*общее*/ template <typename T> pRef<T>::~pRef() {} template <typename T> pRef<T>::pRef(const T* a): pointer(a) {} template <typename T> pRef<T>::pRef(pRef<T>&& other) : pointer(other.pointer) {} template <typename T> pRef<T>& pRef<T>::operator=(pRef<T>&& other) { pointer = other.pointer; return *this; } template <typename T> pRef<T>::operator T() { return get(); } template <typename T> pRef<T> pRef<T>::operator[] (const int index) { return pRef<T>(pointer + index); } //------------------------------------------------- using pgm_int = pRef<int>; using pgm_uint8_t = pRef<uint8_t>; using pgm_uint16_t = pRef<uint16_t>; using pgm_uint32_t = pRef<uint32_t>; using pgm_float = pRef<float>;Странные фермеры нонче пошли: спрашивают в названии темы "как в конструктор передать", а потом пишут:
Нафига мне его писать в примитивном примере, когда можно сразу проинициализировать все свойства класса, без конструктора.
Ты эта - с внутренним Наполеоном сначала договорись, а потом раздувай щёки.
Странные фермеры нонче пошли: спрашивают в названии темы "как в конструктор передать", а потом пишут:
Нафига мне его писать в примитивном примере, когда можно сразу проинициализировать все свойства класса, без конструктора.
Ты эта - с внутренним Наполеоном сначала договорись, а потом раздувай щёки.
Ну, как всегда, ушли в сторону от обсуждаемого вопроса. Объясняю: список иницилизации, фактически, вызывает default-конструтор. Т.е. конструктор есть всегда - определенный пользователем, либо default. Впредь я буду писать примеры, чтобы были поняты большинству аудитории. Прошу пардона.
Однако на мой вопрос так и нет ответа. Пока он был просто не понят (((
Здесь.
Извините, я не понял. Не могли бы Вы все-таки пояснить как с помощью этого решить мою задачу?
Ok, вот пример, на котором я остановился. Мне нужно, чтобы текст сидел в PROGMEM, а не в SRAM, при этом был засунут в объект в момент его инициализации.
class A { public: const char* text; }; A a{PSTR("Hello World!")}; void setup() { Serial.begin(9600); Serial.println(a.text); } void loop() { }Ха, ну, во-первых, PSTR можно использовать только внутри функции, о чем компилятор вам наверняка об этом сказал.
Во-вторых, println напечатает вам чушь. Надо же сначала извлечь строку из PROGMEM.
Во-вторых, println напечатает вам чушь. Надо же сначала извлечь строку из PROGMEM.
О, спасибо! Но как лучше это сделать?
Не хватает модерации этому форму. Вот на arduino.cc люди, почему-то, общаются интеллигентнее. А здесь - новичкам постоянно что-то прилетает. Причем не по дело и не в тему, а так, просто, лишь бы буркнуть что-то.
Ну не хочется помочь человеку, ну не въехать сразу что за хрень написал человек - ну имей же мужество пройти мимо. Нафига флудить то.
Решение есть, но я пройду мимо. Пока.
Не хватает модерации этому форму. Вот на arduino.cc люди, почему-то, общаются интеллигентнее.
Ты мазохист, или да? Если на arduino.cc сплошь белая кость, а тебя тошнит от нас, смердов - так и шёл бы туда, что тебя останавливает? Здесь нам твои душещипательные лекции о несправедливости мироустройства - зачем?
Спрашивай, чо непонятно
class TClass { protected: PFlashString classname; // имя класса сидит в PROGMEM public: TClass() { classname = F("TClass"); };отдается элементарна
PFlashString GetClassName(void) const { return classname;}PFlashString описан как:
Не хватает модерации этому форму. Вот на arduino.cc люди, почему-то, общаются интеллигентней
Тоись кинуть всем в лицо "ардуинщики в С++ не разбираются" и одновременно просить их же разобраться в бреде, который сам себе напридумал - верх интеллигентности штоли?
К слову, инфа для человека, разбирающегося в С++ получше всяких там ардуинщиков: сеттеры/геттеры в ООП ещё в школе учат юзать, а не лазить напрямую к членам класса.
Во-вторых, println напечатает вам чушь. Надо же сначала извлечь строку из PROGMEM.
О, спасибо! Но как лучше это сделать?
Вот полностью работающий ваш пример, если оставить класс как есть:
class A { public: const char* text; }; #define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper *>(pstr_pointer)) void setup() { A a{PSTR("Hello World!")}; Serial.begin(9600); Serial.println(FPSTR(a.text)); } void loop() { }Спрашивай, чо непонятно
struct A { const __FlashStringHelper* f_str; }; void setup() { A a{F("Hello World!")}; Serial.begin(9600); Serial.println(a.f_str);Не увидел никаких противоречий сказанному мною.
Кому интересно что это и как это работает: https://en.cppreference.com/w/cpp/language/default_constructor и https://en.cppreference.com/w/cpp/language/initializer_list
Рад был помочь. Пиво сюда, пожалуйста: jarduino.ru@gmail.com
;-)
Пора открывать донат...
правильно место )
Не увидел никаких противоречий сказанному мною.
Потому и не увидел, что понимания нет. Когда возникнет следующая проблема и соберёшься снова прийти на форум нас поучить, вспомни об этом.
Господа!
Мне показалось, что топикстартер хотел бы разместить данные (строки) в памяти программ на этапе компиляции, а вовсе не в период выполнения, поскольку никакого смысла в таком действии я не вижу: никакой экономии! Такое размещение вполне возможно и я попытаюсь проиллюстрировать это, выпилив часть своего проекта.
файл h
typedef size_t (*FuncFormat)(uint16_t); // тип функции преобразования данных. Возвращает // длину строки // Структура данных в памяти программ typedef const struct{ const char* PROGMEM HelpTxt; // Поясняющий текст const uint16_t Min; // Минимальное значение параметра const uint16_t Max; // Максимальное значение параметра const uint16_t Divider; // Масштабирующий коэфициент const uint16_t IndexDest; // Индекс ячейки сохранения FuncFormat Func; // Указатель на функцию } TParamStruct; // Буферная структура данных в памяти struct TStructPrm{ const char* PROGMEM HelpTxt=NULL; // Поясняющий текст uint16_t Min=0; // Минимальное значение параметра uint16_t Max=0; // Максимальное значение параметра uint16_t Divider=1; // Масштабирующий коэфициент uint16_t IndexDest=0; // Индекс ячейки сохранения FuncFormat Func=NULL; // Указатель на функцию }; volatile struct TStructPrm Prm; // Структура данных в памяти данных // Макрос для загрузки данных в память программ #define MAKE_PRM(Name, Text, Min, Max, Div, Dest, Func) \ const char s##Name[] PROGMEM=Text; \ TParamStruct PROGMEM Name={s##Name, Min, Max, Div, Dest, Func}И файл cpp
// Некоторая функция. Возвращает 1 size_t AnyFunc( uint16_t value ){ Debug.print("value="); Debug.print(Value); return 1; } //Создаём блок данных ExampleDat в памяти программ MAKE_PRM(ExampleDat, "Пример строки 12345", 1, 31, 1, 3, AnyFunc); // Функция вывода структуры (для примера) void OutStruct( const TParamStruct* prm ){ uint16_t Value; for( uint8_t i=0; i<sizeof(TParamStruct)/sizeof(uint16_t); i++ ) // Загрузка данных из структуры *((uint16_t*)&Prm+i)=pgm_read_word((uint16_t*)ps+i); // в PROGMEM в структуру Prm Debug.print((PGM_P)Prm.HelpTxt); Value=Prm.IndexDest/Prm.Divider; if( Prm.Func ){ Prm.Func(Value); Debug.print(" min_v=");Debug.print(Prm.Min); Debug.print(" max_v=");Debug.println(Prm.Max); } // Ну и вызов этой функции OutStruct( &ExampleDat );Этот пример показывает как разместить структуру, состоящую из различных типов данных, в памяти программ на этапе компиляции ну и как к ней обратиться. Надеюсь, что мое сообщение будет полезно. (при "выпиливании" могли закрасться ошибки, но код работал)
Этот пример показывает ....
как делать не надо.
а нафига засовывать всю строку в структуру? Почему не положить строку в Прогмем обычным образом, а в структуры вставить ссылку на нее?
Именно так: в структуре - ссылка на строку в памяти программ. Структура - это лишь тип данных она взята для примера. Я показал как её разместить в памяти программ на этапе компиляции и как с ней работать. Согласен, для темы инфа избыточна.
Я спрашивал совсем иное. С одной стороны, у меня возникла трудность использования PSTR и F в параметрах инициализации объекта, при его инициализации вне функции.
С другой стороны, я и вообще не понимал, как работает перекачка данных между SRAM и PROGMEM.
Я уже сказал, что с этим разобрался.
Что же касается первой части, то, конечно, пришлось делать все подобные инициализации внутри функции. Так это работает.
А заталкивать в PROGMEM иных структур, кроме строк, у меня необходимости пока не возникло. Но спасибо.
Было бы что и куда заталкивать , а затолкать можно многое,и в частности PROGMEM
/**/ void func_P(byte n, const char * title, ... ) { va_list ap; const char * message; int i = 0; va_start( ap, title ); if (n == i)Serial.println((const __FlashStringHelper *)title); message = va_arg( ap, const char * ); while (message) { ++i; if (n == i) Serial.println((const __FlashStringHelper *)message); message = va_arg( ap, const char *); } va_end( ap ); } void aaa(byte n) { func_P( n, PSTR("Dashing through the snow,"), PSTR("in a one - horse open sleigh."), PSTR("O'er the fields we go,"), PSTR("laughing all the way."), PSTR("Bells on bobtails ring,"), PSTR("making spirits bright."), PSTR("What fun it is to ride and sing"), PSTR("a sleighing song tonight."), PSTR(""), PSTR("Oh! Jingle bells, jingle bells,"), PSTR("jingle all the way."), PSTR("Oh what fun it is to ride"), PSTR("in a one-horse open sleigh. Hey!"), 0 //<-- конец ); } void setup() { Serial.begin(9600); for (int i = 13; i >= 0; --i)aaa(i); } void loop() { }