И, кстати, кто Вам сказал, что файлы с данными “обычно” имеют расширение .h? Вы совершенно правильно написали, что
Но именно описания структур данных, а не сами данные как у Вас. Сами данные обычно располагаются в файлах с расширением .c.
Размещение данных в файлах с расширением .h противоречит самой их идее, т.к. в этом случае нельзя такие .h файлы включать в несколько файлов проекта (данные должны определяться один раз). Да, gcc разберётся и не будет два раза включать в исполняемый файл одинаковые константы, но это нарушение.
Так принято поступать в мире ардуино из-за несовершенства IDE, но это именно костыль для залатывания дыры, а не норма.
МММ, раз ты написал, что тебе вариант “откомпилировать с каждым вариантом”, то в “большом” мире это решается или пользованием подгружаемой библиотеки (.so или .dll) - для исполняемого кода или загрузкой файла данных - для данных.
Давайте на примере.
Вот есть у вас задача - перекрутить 10 тыс текстовых документов из WIN1251 в KOI8.
Как мы будем ее решать? - очевидно, напишем программу-фильтр, которая на входе принимает поток байт, вычисляет среди них те, что относятся к диапазону одной кодировки, заменяет их на соответвующие из другой кодировки и выкидывает поток на выход.
А теперь представим, что некий идиот сохранил эти документы не в виде текста, а в виде Гекс-кода. Причем не чистого гекс-кода (для которого есть соответвующие утилиты) - а оформил этот гекс-код в виде текстовых массивов Си.
Так вот, мой вопрос заключается в следующем - как мне прочитать массив Си из текстового файла в ран-тайм, не подключая его директивой инклюд в момент компиляции?
А все остальное - для чего это делать и как этот массив будет потом использоваться - дело десятое, к вопросу отношения не имеет.
Если и сейчас непонятно написал, то значит умение обьяснять мне полностью изменило и тогда прошу у всех прощения за отнятое время.
Как? - просто не делать этого. Помнишь очаровательный ролик на ютубе про доктора-психолога: “Stop it!”?
ссылку ниже положу… специально для Рокфора.
Как прочесть текстовый файл из контроллера? А если не из контроллера, а на сравнительно большой железке - то никаких вопросов - написать простой парсер. В целом ко-пилот справится. Или давай я, в рамках продолжения лекций по синтаксическому анализу?
я согласен и понимаю те проблемы, которые это создает.
Но почему-то файлы шрифтов принято сохранять в файлах .h, причем не только в Ардуино. Какая-то странная традиция…
Я бы, исходя из деталей задачи (в которых, как известно, чорт притаился) или
Написал бы парсер.
Или
С помощью GCC: скомпилировал бы 100500 этих бинарников, а затем бы выуживал из них нужные секции. Но говорю, тут все от деталей зависит. Если у тебя можно все в .data кинуть, то это хорошо. Если нет, то нужно будет к каждому массиву в си-коде приписать attribute((section … и дать имя. Например, .rodata1, .rodata2 и так далее. Затем бы загружал эти секции из бинарников, благо код уже есть написанный (загрузить секцию такую-то из .o файла, или из .elf)
Или
Приписал бы к каждому такому си-файлу main(), который переконверчивает и сохраняет данные в нужно виде, и запустил бы на ночь
Да, спасибо. Как я уже написал выше, я уже решил вопрос примерно этим же способом (только вместо шелла использовал GNU make - там, имхо, телодвижений получается меньше.
Но компилировать для каждого фонта отдельный экземпляр программы кажется мне оверхедом… (может я не прав).
Собственно тема и была открыта чтобы спросить - нет ли более “прямого” пути. Если нет - значит на том и заканчиваем.
ну не только поэтому. При использовании файловой системы шрифты придется либо подгружать в оперативку, либо каждый раз читать из файла. Первое - расточительно, второе медленно. А из хедера они попадают напрямую в флеш.
Мы, кстати, как-то давно придумали решение для embedded: типа, нужна файловая система, нужно в нее как-то файлы переливать, геморрой.
Решение было такое:
обычным tar’ом создавался образ файловой системы. Ну, просто на каталог ее натравливали, где наши файлы и каталоги были. Получаем .tar файл.
Затем, (на самом деле это делается один раз только) в файле линкера (.ld) создавалась секция с бинарными данными, куда инклюдился .tar файл.
В результате, после компиляции, линкер склеивал все вместе и так и прошивали.
Софт же наш, благо адрес секции есть, просто из памяти читал данные: даже написали маленький драйвер TAR_FS, и пользовались обычными fread, fwrite.