Простая вроде задача... много C-type структур в текстовых .h файлах - как обработать пакетом?

Так и есть.

И, кстати, кто Вам сказал, что файлы с данными “обычно” имеют расширение .h? Вы совершенно правильно написали, что

Но именно описания структур данных, а не сами данные как у Вас. Сами данные обычно располагаются в файлах с расширением .c.

Размещение данных в файлах с расширением .h противоречит самой их идее, т.к. в этом случае нельзя такие .h файлы включать в несколько файлов проекта (данные должны определяться один раз). Да, gcc разберётся и не будет два раза включать в исполняемый файл одинаковые константы, но это нарушение.

Так принято поступать в мире ардуино из-за несовершенства IDE, но это именно костыль для залатывания дыры, а не норма.

МММ, раз ты написал, что тебе вариант “откомпилировать с каждым вариантом”, то в “большом” мире это решается или пользованием подгружаемой библиотеки (.so или .dll) - для исполняемого кода или загрузкой файла данных - для данных.

Дочитал до фразы

в четвёртом абзаце и дальше читать не стал. Уровень грамотности автора понятен, читать дальше смысла нет.

хммм… что ж так сложно-то все :slight_smile:

Давайте на примере.
Вот есть у вас задача - перекрутить 10 тыс текстовых документов из WIN1251 в KOI8.
Как мы будем ее решать? - очевидно, напишем программу-фильтр, которая на входе принимает поток байт, вычисляет среди них те, что относятся к диапазону одной кодировки, заменяет их на соответвующие из другой кодировки и выкидывает поток на выход.

А теперь представим, что некий идиот сохранил эти документы не в виде текста, а в виде Гекс-кода. Причем не чистого гекс-кода (для которого есть соответвующие утилиты) - а оформил этот гекс-код в виде текстовых массивов Си.

Так вот, мой вопрос заключается в следующем - как мне прочитать массив Си из текстового файла в ран-тайм, не подключая его директивой инклюд в момент компиляции?

А все остальное - для чего это делать и как этот массив будет потом использоваться - дело десятое, к вопросу отношения не имеет.

Если и сейчас непонятно написал, то значит умение обьяснять мне полностью изменило и тогда прошу у всех прощения за отнятое время.

Как? - просто не делать этого. Помнишь очаровательный ролик на ютубе про доктора-психолога: “Stop it!”? :wink:
ссылку ниже положу… специально для Рокфора.
Как прочесть текстовый файл из контроллера? А если не из контроллера, а на сравнительно большой железке - то никаких вопросов - написать простой парсер. В целом ко-пилот справится. Или давай я, в рамках продолжения лекций по синтаксическому анализу? :wink:

что-то я торможу… из какого контроллера? Тем более что ты написал, что этого вообще делать не надо

я согласен и понимаю те проблемы, которые это создает.
Но почему-то файлы шрифтов принято сохранять в файлах .h, причем не только в Ардуино. Какая-то странная традиция…

Теперь я торможу… :disguised_face: Ты ж сам написал “в ран тайм”? Так на компе или из МК? Из МК - никак. На компе - нет проблем.

Понятно.

Задача решается таким образом.

Пишете программу A на Си,

  1. принимает один параметр - название будущего файла;
  2. включает один из Ваших "шрифтов частным #include “kaka.h”
  3. делает всё, что нужно и сохраняет результат в файле, имя которого задано параметром;

Далее на шелловском скрипте (в случае Windows, можно на JScript) пишете программку, которая:

  1. просматривает директорию с Вашими “шрифтами”
  2. по одному копирует файлы шрифтов в директорию программы A под именем kaka.h;
  3. затем запускает компилятор (версию командной строки)
  4. а потом скомпилированную программу А, передав ей параметром оригинальное имя файла-шрифта.
  5. Когда та сделает своё дело, шелл-программа копирует следующий шрифт туда же по именем kaka.h и всё повторяется до тех пор, пока не обработает все.

Как-то так.

на компе.

Я бы, исходя из деталей задачи (в которых, как известно, чорт притаился) или

  1. Написал бы парсер.
    Или
  2. С помощью GCC: скомпилировал бы 100500 этих бинарников, а затем бы выуживал из них нужные секции. Но говорю, тут все от деталей зависит. Если у тебя можно все в .data кинуть, то это хорошо. Если нет, то нужно будет к каждому массиву в си-коде приписать attribute((section … и дать имя. Например, .rodata1, .rodata2 и так далее. Затем бы загружал эти секции из бинарников, благо код уже есть написанный (загрузить секцию такую-то из .o файла, или из .elf)
    Или
  3. Приписал бы к каждому такому си-файлу main(), который переконверчивает и сохраняет данные в нужно виде, и запустил бы на ночь :slight_smile:
1 лайк

Никогда не замечал такой традиции.

Кстати, вот прямо сейчас заглянул:

Да, спасибо. Как я уже написал выше, я уже решил вопрос примерно этим же способом (только вместо шелла использовал GNU make - там, имхо, телодвижений получается меньше.

Но компилировать для каждого фонта отдельный экземпляр программы кажется мне оверхедом… (может я не прав).

Собственно тема и была открыта чтобы спросить - нет ли более “прямого” пути. Если нет - значит на том и заканчиваем.

Плохая. .h файл не компилируется в отдельный объектный модуль и поэтому очень нехорошо размещать объект в нем.

Почему-то в оригинальной библиотеке Adafruit-GFX все шрифты в .h файлах…

Link:

Так Вы же их не сохраняете, сохраняются только результаты их работы. А компилируете Вы их прямо поверху - не вижу никакой проблемы.

Ну вот и отлично!

Всем спасибо!

В хедерах данные обычно хранят в случае, если с файловой системой возиться не хочется. Нет ее, например.

Представь, для начала, что тебе надо еще и файловую систему, еще и перелить туда файлы шрифтов, потом только свой скетч прошивать.

ну не только поэтому. При использовании файловой системы шрифты придется либо подгружать в оперативку, либо каждый раз читать из файла. Первое - расточительно, второе медленно. А из хедера они попадают напрямую в флеш.

Мы, кстати, как-то давно придумали решение для embedded: типа, нужна файловая система, нужно в нее как-то файлы переливать, геморрой.

Решение было такое:
обычным tar’ом создавался образ файловой системы. Ну, просто на каталог ее натравливали, где наши файлы и каталоги были. Получаем .tar файл.

Затем, (на самом деле это делается один раз только) в файле линкера (.ld) создавалась секция с бинарными данными, куда инклюдился .tar файл.

В результате, после компиляции, линкер склеивал все вместе и так и прошивали.

Софт же наш, благо адрес секции есть, просто из памяти читал данные: даже написали маленький драйвер TAR_FS, и пользовались обычными fread, fwrite.

1 лайк