pyroman 2 3 мая, 2023 Опубликовано 3 мая, 2023 · Жалоба Добрый день, уважаемые. void Func (char* str) Func ("Hello, World!") Имеем, для примера, такой вот заголовок функции и пример обращения. В Func передаётся указатель на строку, строку компилятор помещает во flash и это хорошо! Необходимо сделать, для примера: typedef struct { int A; int B; float C; } Data; void Func (Data* data) ? Func ({12, 10, 145.78}) ? Т.е. непонятно, как описать функцию, чтобы компилятор разместил структуру во flash и передал её указатель в функцию, как это было со строкой. Со строкой же это работает... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 3 мая, 2023 Опубликовано 3 мая, 2023 · Жалоба typedef struct { int A; int B; float C; } Data; const Data data = { 12, 10, 145.78 }; .... void Func (Data* data) { .... } ..... Func (&data); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 3 мая, 2023 Опубликовано 3 мая, 2023 · Жалоба 23 минуты назад, pyroman сказал: void Func (char* str) Func ("Hello, World!") Имеем, для примера, такой вот заголовок функции и пример обращения. В Func передаётся указатель на строку, строку компилятор помещает во flash и это хорошо! И это плохо. Так как функция описана как принимающая указатель на char *, а значит - предполагается, что она будет менять содержимое str. А по факту передаёте ей указатель на char const *. Что чревато вылетом в исключение. Или крестик снимите или трусы наденьте Или функцию объявляйте как void Func(char const *str) или не передавайте ей константы в аргументе. 13 минут назад, Forger сказал: const Data data = { 12, 10, 145.78 }; .... void Func (Data* data) { .... } ..... Func (&data); И вам - аналогично. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pyroman 2 3 мая, 2023 Опубликовано 3 мая, 2023 (изменено) · Жалоба 37 minutes ago, jcxz said: Или функцию объявляйте как void Func(char const *str) или не передавайте ей константы в аргумент Спасибо, но не суть. Вопром в том, как же объявить константную структуру именно, как аргумент/в аргументе функции? Это для чего, собственно: имеем множество вызовов функции с разными исходными данными, которые константы, но разные. Чтобы удобнее было читать исходник, сразу видеть, что передаётся в функцию, как с Func ("Hello, World!") Изменено 3 мая, 2023 пользователем pyroman Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 3 мая, 2023 Опубликовано 3 мая, 2023 · Жалоба 32 minutes ago, jcxz said: Что чревато вылетом в исключение. В данном случае специально убрано все "лишнее", иначе это еще больше запутает новичка )) 5 minutes ago, pyroman said: как же объявить константную структуру именно, как аргумент/в аргументе функции? Внутри вызова функции в си - никак. В плюсах еще можно по-изголяться с шаблонами, но вам оно надо? 😉 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
amaora 25 3 мая, 2023 Опубликовано 3 мая, 2023 · Жалоба #define Func2(...) do { const Data t = __VA_ARGS__; Func(&t); } while (0) typedef struct { int A; int B; float C; } Data; void Func(Data *d) { printf("%i %i %f\n", d->A, d->B, d->C); } int main() { Func2({3,4,6.7}); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 3 мая, 2023 Опубликовано 3 мая, 2023 · Жалоба 17 минут назад, pyroman сказал: Вопром в том, как же объявить константную структуру именно, как аргумент/в аргументе функции? Это для чего, собственно: имеем множество вызовов функции с разными исходными данными, которые константы, но разные. Чтобы удобнее было читать исходник, сразу видеть, что передаётся в функцию, как с Func ("Hello, World!") Воспользуйтесь макросами: struct Qqq { int a, b; }; void Func(Qqq const *pq) { ... } #define FuncConst(...) { \ static Qqq const t = __VA_ARGS__; \ Func(&t); \ } ... FuncConst({1, 2}); FuncConst({2, 3}); 12 минут назад, amaora сказал: #define Func2(...) do { const Data t = __VA_ARGS__; Func(&t); } while (0) typedef struct { int A; int B; float C; } Data; void Func(Data *d) { printf("%i %i %f\n", d->A, d->B, d->C); } int main() { Func2({3,4,6.7}); } То, что do { .. } while (0) использовали - хорошо. А то, что про static (в const Data t) и про const (в аргументе функции) забыли - плохо. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 3 мая, 2023 Опубликовано 3 мая, 2023 · Жалоба Если компилятор gcc (или совместимый), то можно использовать его расширение: #define CONST(Type, ...) ({static const Type var = {__VA_ARGS__}; &var}) func(CONST(MyStruct, 1, 2, 3, 4)) Преимущество - один макрос на любое количество функций и типов параметров, недостаток - только gcc (и примкнувшие к нему) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pyroman 2 3 мая, 2023 Опубликовано 3 мая, 2023 · Жалоба Спасибо всем, макрос работает, проверил. Ещё вопрос. Почему макрос не работает должным образом (компилятор передаёт структуру в функцию через стек) без ключевого слова static? Со static полный порядок - имеем указатель на структуру во flash. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 3 мая, 2023 Опубликовано 3 мая, 2023 · Жалоба 2 часа назад, pyroman сказал: Ещё вопрос. Почему макрос не работает должным образом (компилятор передаёт структуру в функцию через стек) без ключевого слова static? Со static полный порядок - имеем указатель на структуру во flash. Макрос и компилятор работают должным образом, так как не указывая static, вы тем самым сами указываете ему создавать объект в автоматической памяти (на стеке). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pyroman 2 7 мая, 2023 Опубликовано 7 мая, 2023 · Жалоба #define fillRect(x0, y0, x1, y1, flags) fillRect_(y0<<8 | x0, y1<<8 | x1, flags) void fillRect_(unsigned long param0, unsigned long param1, unsigned long flags) fillRect(0, 0, 127, 63, DRAW_OR); По итогу, применил вот так вот. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 7 мая, 2023 Опубликовано 7 мая, 2023 · Жалоба 1 hour ago, pyroman said: По итогу, применил вот так вот. И где тут 'структура во FLASH' с которой всё начиналось? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pyroman 2 7 мая, 2023 Опубликовано 7 мая, 2023 (изменено) · Жалоба 1 hour ago, xvr said: И где тут 'структура во FLASH' с которой всё начиналось? typedef struct { signed long x0; signed long y0; signed long x1; signed long y1; unsigned long flags; } Rect; #define fillRect(...) { \ static const Rect t = __VA_ARGS__; \ fillRect_(&t) \ } void fillRect_(Rect* param0) { } fillRect({0, 0, 127, 63, DRAW_OR}) Вариант Б 🙂 Изменено 7 мая, 2023 пользователем pyroman Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 7 мая, 2023 Опубликовано 7 мая, 2023 · Жалоба 1 hour ago, pyroman said: Вариант Б 🙂 если исправить ошибки, то вот так собирается: typedef struct { signed long x0; signed long y0; signed long x1; signed long y1; unsigned long flags; } Rect; void fillRect_(const Rect* param0) { } #define fillRect(...) { \ static const Rect t = __VA_ARGS__; \ fillRect_(&t); \ } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 85 7 мая, 2023 Опубликовано 7 мая, 2023 · Жалоба А в чем сопсна проблема то? Пишите структуру, объявляете переменную типа структуры с квалификатором const. Далее - забота линкера. Если его скрипт написан верно, то в нем будет секция .rodata, которая опознает все const и кладет туда, куда в ней сказано, то есть в область FLASH, которая, в свою очередь, так же должна быть верно описана и в ней указаны адрес начала флеша. И квалификатор const в параметре функции защищает на уровне компиляции от изменений константного значения, хранящегося во флеще: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться