Как кросс-платформенно встраивать бинарные ресурсы в программу? - PullRequest
0 голосов
/ 26 октября 2018

Мы разрабатываем приложения на C ++ для Windows, Mac и Linux. В приложении много бинарных ресурсов, и по какой-то причине нам нужно упаковывать их в исполняемый бинарный файл, а не класть в каталоги (или в комплект Apple App).

В настоящее время мы используем скрипт, чтобы преобразовать эти ресурсы в константы массива C ++, а затем скомпилировать и связать их. Однако этот подход имеет так много недостатков:

  • Вы должны скомпилировать исходный код ресурса, это занимает много времени и не является необходимым по необходимости.
  • Исходные коды ресурса будут проанализированы IDE. Поскольку они большие, аналитика кода сильно замедляется.
  • MSVC имеет ограничение на размер исходного кода, поэтому большие ресурсы (несколько МБ) должны быть разделены на множество частей, а затем объединены во время выполнения.

После некоторого изучения я нашел несколько решений:

  • В Windows я могу использовать .rc файлы и связанные с ними WinAPI.
  • В Linux я могу напрямую конвертировать произвольный двоичный файл в файл obj через objcopy.

Однако есть еще несколько вопросов:

  • Использование WinAPI для извлечения ресурсов требует множества функций для доступа к одному ресурсу. Есть ли более простые способы в Windows?
  • Как это сделать в Mac?

1 Ответ

0 голосов
/ 26 октября 2018

Довольно распространенный прием, наиболее часто используемый для самораспаковывающихся архивов или языка сценариев для исполняемых компиляторов, заключается в добавлении ресурсов в конец исполняемого файла.

Windows:

copy app.exe+all-resources app-with-resources.exe

Linux:

cp executable executable-with-resources
cat all-resources >>executable-with-resources

Затем вы можете прочитать свой собственный исполняемый файл, используя, например, fopen(argv[0]).Чтобы перейти в правильную позицию, то есть в начало ресурсов, возможное решение - сохранить размер исполняемого файла без ресурсов в качестве последнего слова файла.

FILE* fp = fopen(argv[0], "rb");
fseek(fp, -sizeof(int), SEEK_END);
int beginResourcesOffset;
fread(&beginResourcesOffset, 1, sizeof(int), fp);
fseek(fp, beginResourcesOffset, SEEK_SET);

Будьте осторожны с этим решением, хотяАнтивирус на окнах иногда не нравится.Возможно, есть лучшие решения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...