コンパイル時に、バイナリ
データを
実行可能ファイルに
埋め込み、プログラムコードから
利用する方法。
(caseih と coderJeff のフォーラム投稿に基づく)
この記事では、コンパイルされたプログラムにバイナリデータを含める方法と、これらにアクセスする方法について説明します。
原理
(G)LDリンカー(FreeBASIC 配付に含まれています)は、ファイル内のバイナリデータをオブジェクトファイルに変換することで処理できます。
このオブジェクトファイルは、データを読み取るためにプログラムコードからアクセスできるシンボルをエクスポートします。
リンカは、提供されたファイル名に基づいて2バイトのシンボルを作成します:
-データブロックの先頭の記号(最初のデータバイト)、
-データブロックの終わりを表す別の記号(最後のデータバイトの直後)。
ユーザープログラムをオブジェクトファイルでコンパイルすることにより、これらのバイト記号のアドレスにより、データの最初と最後へのポインタを取得できます。
注:この原理を、たとえば、実行可能ファイルに含めることができる音声データファイルに適用すると有利な場合があります。
音声データの開始ポインタと音声データのサイズの両方を、任意の音声プレーヤー機能に渡すことができます。
例
原理だけを示す簡単な例(linux/win 32/64ビット gas/gas64/gcc でテスト済み)。
この例では、
hello.txt テキストファイルに挿入されたテキストの ASCII コードバイトをバイナリデータとして使います:
例として
hello.txt テキストファイル:
Hello!
Welcome to the forum.
LD リンカーを手動で呼び出して、
hello.txt テキストファイルを
hello.o オブジェクトファイルに変換し、記号をエクスポートします:
...\ld -r -b binary -o hello.o hello.txt
2バイトの記号が
hello.o オブジェクトファイルからエクスポートされます:
- Windows 32-bit で:
binary_hello_txt_start : データブロックの先頭(最初のデータバイト)
binary_hello_txt_end : データブロックの終わり(最後のデータバイトの直後)
- その他:
_binary_hello_txt_start : データブロックの先頭(最初のデータバイト)
_binary_hello_txt_end : データブロックの終わり(最後のデータバイトの直後)
次のプログラムをコンパイルするときに、コマンドラインに
hello.o オブジェクトファイルを含めます(実行可能ファイルに埋め込まれた ASCII コードバイトを出力するプログラム):
Extern "C"
#if defined(__FB_WIN32__) And Not defined(__FB_64BIT__)
Extern hello_txt_start Alias "binary_hello_txt_start" As Const Byte
Extern hello_txt_end Alias "binary_hello_txt_end" As Const Byte
#else
Extern hello_txt_start Alias "_binary_hello_txt_start" As Const Byte
Extern hello_txt_end Alias "_binary_hello_txt_end" As Const Byte
#endif
End Extern
Dim hello_ptr As Const Byte Const Ptr = @hello_txt_start
Dim hello_length As Const UInteger = @hello_txt_end - @hello_txt_start
For i As UInteger = 0 To hello_length - 1
Print Chr(hello_ptr[i]);
Next
Print
Sleep
参照