Как видно из этого другого вопроса о objcopy
, еще один способ включить двоичный файл в исполняемый файл заключается в использовании директивы ассемблера .incbin
. Это решение имеет два основных преимущества по сравнению с objcopy
: разработчик контролирует имена символов (у objcopy
, похоже, есть фиксированная схема их именования), и, ну, objcopy
не требуется.
Решение также имеет преимущества по сравнению с решением -sectcreate
на основе компоновщика. Он кроссплатформенный, и доступ к данным намного проще.
Я использую этот сценарий правила сборки Xcode для создания файла, который нужно включить, и файла сборки с директивой .incbin
:
my_generation_tool -o $DERIVED_FILE_DIR/$INPUT_FILE_NAME.out $INPUT_FILE_PATH
export AS_PATH=$DERIVED_FILE_DIR/$INPUT_FILE_NAME.out.s
echo "\t.global _data_start_$INPUT_FILE_BASE" > $AS_PATH
echo "\t.global _data_end_$INPUT_FILE_BASE" >> $AS_PATH
echo "_data_start_ $INPUT_FILE_BASE:" >> $AS_PATH
echo "\t.incbin \"$INPUT_FILE_NAME.out\"" >> $AS_PATH
echo "_data_end_$INPUT_FILE_BASE:" >> $AS_PATH
Тогда для файла «somefile.gen», который обрабатывается этим правилом, сборка будет выглядеть так:
.global _data_start_somefile
.global _data_end_somefile
_data_start_somefile:
.incbin "somefile.gen.out"
_data_end_somefile:
Доступ к данным на языке C можно получить с помощью символов data_start_somefile
и data_end_somefile
(компоновщик macOS ставит перед именами C фиктивный префикс _
, поэтому они есть в файле сборки):
extern char data_start_somefile, data_end_somefile;
for (const char* c = &data_start_somefile; c != &data_end_somefile; ++c)
{
// do something with character
}
Ответ в другой ветке содержит больше наворотов, которые некоторые люди могут найти полезными (например, символ length
).
person
zneak
schedule
06.01.2016