GNU/Linux >> Linux の 問題 >  >> Linux

GCC を使用した C/C++:リソース ファイルを実行可能ファイル/ライブラリに静的に追加する

imagemagick を使用:

convert file.png data.h

次のようなものを与えます:

/*
  data.h (PNM).
*/
static unsigned char
  MagickImage[] =
  {
    0x50, 0x36, 0x0A, 0x23, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 
    0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4D, 0x50, 0x0A, 0x32, 0x37, 
    0x37, 0x20, 0x31, 0x36, 0x32, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0xFF, 0xFF, 
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 

....

他のコードとの互換性のために、 fmemopen のいずれかを使用できます 「通常の」FILE * を取得するには オブジェクト、または代わりに std::stringstream iostream を作る . std::stringstream ただし、これには適していません。もちろん、イテレータを使用できる場所ならどこでもポインタを使用できます。

automake でこれを使用している場合は、BUILT_SOURCES を適切に設定することを忘れないでください。

この方法の良い点は次のとおりです。

<オール>
  • テキストを出力するので、バージョン管理とパッチ適用が適切に行われます
  • 移植可能で、すべてのプラットフォームで明確に定義されています

  • ld を使用してバイナリ ファイルを実行可能ファイルに埋め込むことができます linker.たとえば、ファイル foo.bar がある場合 次に、次のコマンドを ld に追加して、実行可能ファイルに埋め込むことができます

    --format=binary foo.bar --format=default
    

    ld を呼び出している場合 gccまで -Wl を追加する必要があります

    -Wl,--format=binary -Wl,foo.bar -Wl,--format=default
    

    こちら --format=binary 次のファイルがバイナリであり、--format=default であることをリンカに伝えます。 デフォルトの入力形式に戻ります (これは、foo.bar の後に他の入力ファイルを指定する場合に便利です) ).

    次に、コードからファイルのコンテンツにアクセスできます:

    extern uint8_t data[]     asm("_binary_foo_bar_start");
    extern uint8_t data_end[] asm("_binary_foo_bar_end");
    

    "_binary_foo_bar_size" という名前のシンボルもあります .タイプ uintptr_t だと思います しかし、私はそれをチェックしませんでした.


    更新 コントロール John Ripley のアセンブリ .incbin を好むようになりました ベースのソリューション オファーを提供し、そのバリアントを使用するようになりました。

    objcopy (GNU binutils) を使用して、バイナリ データをファイル foo-data.bin から実行可能ファイルのデータ セクションにリンクしました。

    objcopy -B i386 -I binary -O elf32-i386 foo-data.bin foo-data.o
    

    これにより、foo-data.o が得られます 実行可能ファイルにリンクできるオブジェクト ファイル。 C インターフェイスは次のようになります

    /** created from binary via objcopy */
    extern uint8_t foo_data[]      asm("_binary_foo_data_bin_start");
    extern uint8_t foo_data_size[] asm("_binary_foo_data_bin_size");
    extern uint8_t foo_data_end[]  asm("_binary_foo_data_bin_end");
    

    のようなことができます
    for (uint8_t *byte=foo_data; byte<foo_data_end; ++byte) {
        transmit_single_byte(*byte);
    }
    

    または

    size_t foo_size = (size_t)((void *)foo_data_size);
    void  *foo_copy = malloc(foo_size);
    assert(foo_copy);
    memcpy(foo_copy, foo_data, foo_size);
    

    ターゲット アーキテクチャに定数データと変数データの格納場所に関する特別な制約がある場合、またはそのデータを .text に格納する場合 プログラムコードと同じメモリタイプに収まるようにセグメント化すると、 objcopy で遊ぶことができます パラメータをもう少し。


    Linux
    1. FTPを使用してASCIIまたはバイナリとしてファイルをアップロードする

    2. Howto:Linux での一時ファイルを使用した C プログラミング

    3. (C/C++) Windows と Linux の両方で実行できる実行可能ファイルを生成する方法は?

    1. Linux で .so ファイルを java.library.path に追加する方法

    2. Clang は GCC でコンパイルされた .a ライブラリでコードをコンパイルできますか?

    3. 正規表現のグループ化は C++ 11 の正規表現ライブラリと一致します

    1. findコマンドを使用してLinux上のファイルとディレクトリを検索します

    2. Linuxでテキストファイルに行番号を追加する方法

    3. c/c++ 静的ライブラリの依存関係を一覧表示するには?