Внедрить текстовый файл в ресурс в собственном приложении Windows

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


person Oliver Zheng    schedule 29.05.2010    source источник


Ответы (2)


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

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

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

nameID typeID filename

где nameID - это некое уникальное 16-битовое целое число без знака, которое идентифицирует ресурс, а typeID - некоторое уникальное 16-битовое целое число без знака больше 255, которое определяет тип ресурса (вы можете определить эти целые числа в файле resource.h). filename - это путь к файлу, двоичное содержимое которого вы хотите встроить в скомпилированный ресурс.

Итак, у вас может быть это так:

In 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().

person In silico    schedule 29.05.2010
comment
У меня есть еще один вопрос общего характера, который задают здесь. Не могли бы вы ответить на мой второй вопрос, связанный с вашим ответом? Как получить файл dll, в котором есть функция, содержащая основной код в вашем ответе. - person utvecklare; 20.02.2016
comment
система удалит их автоматически при выходе из программы. Не все ли программы при выходе из системы освобождают ресурсы? Утечка памяти и утечка ресурсов происходит во время выполнения исполняемого файла. Таким образом, если эта программа загружает n одного и того же ресурса, это приведет к утечке ресурсов. - person Raindrop7; 07.11.2017
comment
В свойствах файла ресурсов есть Null Terminate Strings. - person Laurie Stearn; 20.02.2018
comment
Имею приложение win32. Могу ли я узнать, где я могу найти файл ресурсов и как я могу создать определяемый пользователем файл ресурсов? Я хочу загрузить XML-файл во время самой сборки. Размер файла 20 МБ. - person Programmer; 10.01.2019

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

Есть много вопросов о переполнении стека, которые подробно раскрывают это:

person Stephen    schedule 29.05.2010
comment
-1 PE (+) файлы уже могут хранить пользовательские ресурсы, а инструменты сборки Windows имеют все необходимое. Синтаксис сценария ресурсов задокументирован, а ОС предоставляет API для доступа к этим данным. Этот ответ - ответ на другой вопрос. - person IInspectable; 28.04.2014