web-dev-qa-db-ja.com

ネイティブWindowsアプリケーションのリソースにテキストファイルを埋め込む

C++ Windowsプログラムがあります。一部のデータを含むテキストファイルがあります。現在、テキストファイルは別のファイルであり、実行時に読み込まれ、解析されます。これをバイナリとしてリソースとして埋め込むにはどうすればよいですか?

46
Oliver Zheng

ネイティブWindowsアプリケーションで作業しているので、テキストファイルの内容をコンパイル済みリソースに埋め込むユーザー定義リソースを作成します。

ユーザー定義リソースの形式は MSDNに記載 であり、 それをロードするための関数 です。

次のように、テキストファイルをリソースファイルに埋め込みます。

_nameID typeID filename
_

ここで、nameIDはリソースを識別する一意の16ビット符号なし整数で、typeIDはリソースタイプを識別する255より大きい一意の16ビット符号なし整数です(これらの整数は、 _resource.h_ファイル)。 filenameは、バイナリコンテンツをコンパイル済みリソースに埋め込むファイルへのパスです。

だからあなたはこのようにするかもしれません:

_resource.h_内:

_// Other defines...

#define TEXTFILE        256
#define IDR_MYTEXTFILE  101
_

リソースファイル:

_#include "resource.h"

// Other resource statements...

IDR_MYTEXTFILE TEXTFILE "mytextfile.txt"
_

次に、次のようにロードします(明確にするためにエラーチェックコードは省略しています)。

_#include <windows.h>
#include <cstdio>
#include "resource.h"

void LoadFileInResource(int name, int type, DWORD& size, const char*& data)
{
    HMODULE handle = ::GetModuleHandle(NULL);
    HRSRC rc = ::FindResource(handle, MAKEINTRESOURCE(name),
        MAKEINTRESOURCE(type));
    HGLOBAL rcData = ::LoadResource(handle, rc);
    size = ::SizeofResource(handle, rc);
    data = static_cast<const char*>(::LockResource(rcData));
}

// Usage example
int main()
{
    DWORD size = 0;
    const char* data = NULL;
    LoadFileInResource(IDR_MYTEXTFILE, TEXTFILE, size, data);
    /* Access bytes in data - here's a simple example involving text output*/
    // The text stored in the resource might not be NULL terminated.
    char* buffer = new char[size+1];
    ::memcpy(buffer, data, size);
    buffer[size] = 0; // NULL terminator
    ::printf("Contents of text file: %s\n", buffer); // Print as ASCII text
    delete[] buffer;
    return 0;
}
_

リソースは実行可能ファイルのバイナリに存在するため、実際にリソースを解放する必要はありません。プログラムが終了すると、システムはそれらを自動的に削除します(関数FreeResource()は32ビットで何も実行せず、 64ビットWindowsシステム)。

データは実行可能バイナリにあるため、取得したポインターを介して直接変更することはできません(そのため、LoadFileInResource()関数の実装はポインターを_const char*_に格納します)。そのためには、BeginUpdateResource()UpdateResource()、およびEndUpdateResource()関数を使用する必要があります。

66
In silico