Вставить текстовый файл в ресурс в собственном приложении Windows - PullRequest
45 голосов
/ 29 мая 2010

У меня есть программа на C ++ для Windows. У меня есть текстовый файл, в котором есть некоторые данные. В настоящее время текстовый файл является отдельным файлом, и он загружается во время выполнения и анализируется. Как можно встроить это в двоичный файл как ресурс?

Ответы [ 2 ]

65 голосов
/ 29 мая 2010

Поскольку вы работаете с собственным приложением Windows, вам нужно создать пользовательский ресурс для встраивания содержимого текстового файла в скомпилированный ресурс.

Формат определенного пользователем ресурса задокументирован в MSDN , как и функции для его загрузки .

Вы встраиваете свой текстовый файл в файл ресурсов следующим образом:

nameID typeID filename

где nameID - это некоторое уникальное 16-разрядное целое число без знака, которое идентифицирует ресурс, а typeID - это некоторое уникальное 16-разрядное целое число без знака больше 255, которое идентифицирует тип ресурса (вы можете определить эти целые числа в 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().

0 голосов
/ 29 мая 2010

Вы можете использовать xxd (с машины linux или, возможно, cygwin), чтобы сгенерировать данные для файла .h / .cc.

Существует множество вопросов о переполнении стека, которые подробно рассматриваются на этом вопросе.:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...