ファイルを実行可能ファイルに埋め込む方法は?

c++ executable file
ファイルを実行可能ファイルに埋め込む方法は?

C ++で書かれた小さなデモ実行ファイルがあり、実行前にロードされている5kbのPNG画像1つのみに依存し、作成したピクセルテキストに使用されます。 この1つのファイルのため、1つの実行可能ファイルではなくZIPアーカイブを配布する必要があります。これにより、ダウンロードと「再生」の間に十分な摩擦が生じ、一部のユーザーは試用を思いとどまると思います。

私の質問は、PNGファイル(および実際に他のファイル)を実行可能ファイルまたはソースコードに埋め込み、単一ファイルにし、実行可能ファイルで使用できるようにすることですか?

PNGをバイトストリームとして解析する機能があるため、ピクセルデータに変換する必要はありません。

前もって感謝します! (これに似たタイトルを持つ他の質問が存在しますが、それらとその回答はより具体的な問題になりそうで、あまり役に立ちませんでした)

編集:コンパイラはVisual C ++ 2010であり、これはWindows上にあります(ただし、Windows専用のユーティリティは避けたいと思います)

  • edit2 *:Alfの答えは最も移植性の高い方法のように思えたので、PNGファイルを解析してTXTまたは「unsigned char」配列として読み取ることができるヘッダーファイルに関数をすばやく作成しました。 この形式ではPNGファイル自体と同じように見えますが、私のpngローダーは配列を受け入れません。 それをメモリからロードするとき、PNGパーサーは問題があれば、 `(void * buffer、size_t length)`を取ります。

ご覧になりたいコードですが、この方法よりも優れていると思われる場合は、他の回答も受け入れます。

void compileImagePNGtoBinary(char * filename, char * output){

    FILE * file = fopen(filename, "rb");
    FILE * out = fopen(output, "w");

    unsigned char buffer[32];
    size_t count;
    fprintf(out, "#pragma once \n\n static unsigned char TEXT_PNG_BYTES[] = { ");
    while(!feof(file)){
            count = fread(buffer, 1, 32, file);

            for(int n = 0; n < count; ++n){
                    fprintf(out, "0x%02X, ", buffer[n]);
            };
    };
    fprintf(out, "};");
    fclose(file);
    fclose(out);

};

最終編集:Alfが言及したhttp://www.imagemagick.org/script/command-line-processing.php[ImageMagick]は、私が必要とするものを正確に実行してくれました、ありがとう!

  23  7


ベストアンサー

移植可能な方法は、次のような関数を定義することです

typedef unsigned char Byte;

Byte const* pngFileData()
{
    static Byte const data =
    {
        // Byte data generated by a helper program.
    };
    return data;
}

次に、PNGファイルをバイナリとして読み取り、C ++中括弧初期化テキストを生成する小さなヘルパープログラムを作成するだけです。 編集:@awoodlandは質問へのコメントで指摘しています、https://stackoverflow.com/questions/4864866/cc-with-gcc-statically-add-resource-files-to-executable-library/4864879# 4864879 [ImageMagick]には、このような小さなヘルパープログラムがあります…

もちろん、Windows固有のプログラムの場合は、代わりに通常のWindowsリソーススキームを使用します。

乾杯

10


XDを見てください:

_
最後に、xdはバイナリファイルを読み取り、ファイルからのデータを含むC言語データ宣言を発行できます。 これは、Cプログラム内にバイナリデータを埋め込む場合に便利です。
_

個人的には、Windowsのリソースを使用しますが、実行可能形式の知識を必要としない真に移植可能な方法が必要な場合は、これが最適です。 PNG、JPG、なんでも…​

9


Base64ファイルをエンコードし、コードのどこかに文字列に入れます;)

5


これは実行形式に依存します。つまり、本質的にオペレーティングシステム/コンパイラに依存します。 Windowsは、https://stackoverflow.com/questions/6005520/how-to-embed-resources-into-a-single-executable [この質問]で説明されているように、このためのリソースシステムを提供しています。

4


任意のファイルをプログラムリソースに埋め込むことができます:http://msdn.microsoft.com/en-us/library/aa381054(v=vs.85).aspx[(MSDN)User-Defined Resource]。

__
ユーザー定義のリソース定義ステートメントは、アプリケーション固有のデータを含むリソースを定義します。 データの形式は任意であり、特定のファイルのコンテンツ(filenameパラメーターが指定されている場合)または一連の数字と文字列(rawデータブロックが指定されている場合)のいずれかとして定義できます。

nameID typeID filename

ファイル名は、リソースのバイナリデータを含むファイルの名前を指定します。 ファイルの内容はリソースとして含まれています。 RCは、バイナリデータを解釈しません。 ターゲットコンピュータのアーキテクチャに合わせてデータを適切に調整することは、プログラマの責任です。
__

完了したら、http://msdn.microsoft.com/en-us/library/ms648046(v = VS.85).aspx [LoadResource function]を使用して、ファイルに含まれるバイトにアクセスできます。

3


Linuxではこれを使用します。 これは、少し変更されたものの、4kデモを実行しようとしたときに見つけたいくつかの例に基づいています。 私はそれがWindowsでも機能すると信じていますが、デフォルトのVSインラインアセンブリでは機能しません。 私の回避策は、このコードまたはhttps://stackoverflow.com/a/7288422/1888983[@MarkRansom]が示唆するWindowsリソースシステムを使用するマクロを#definingすることです(動作するのは非常に苦痛ですが、最終的には動作します)。

//USAGE: call BINDATA(name, file.txt) and access the char array &name.

#ifndef EMBED_DATA_H
#define EMBED_DATA_H

#ifdef _WIN32
//#error The VS ASM compiler won't work with this, but you can get external ones to do the trick
#define BINDATA #error BINDATA requires nasm
#else

__asm__(
".altmacro\n" \
".macro binfile p q\n" \
"   .global \\p\n" \
"\\p:\n" \
"   .incbin \\q\n" \
"\\p&_end:\n" \
"   .byte 0\n" \
"   .global \\p&_len\n" \
"\\p&_len:\n" \
"   .int(\\p&_end - \\p)\n" \
".endm\n\t"
);

#ifdef __cplusplus
    extern "C" {
#endif

#define BINDATA(n, s) \
__asm__("\n\n.data\n\tbinfile " #n " \"" #s "\"\n"); \
extern char n; \
extern int n##_len;

#ifdef __cplusplus
    }
#endif

#endif

#endif

0


タイトルとURLをコピーしました