将文本文件嵌入本地Windows应用程序资源中

53

我有一个C++ Windows程序。我有一个文本文件,其中包含一些数据。目前,这个文本文件是一个单独的文件,并且在运行时加载和解析。如何将其作为资源嵌入到二进制文件中?

2个回答

80

由于你正在开发一个本地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;
}
请注意,你实际上不必释放资源,因为资源位于可执行文件的二进制文件中,当程序退出时系统会自动删除它们(32位和64位 Windows 系统上的函数 FreeResource() 不起作用)。
由于数据位于可执行二进制文件中,你不能直接通过检索到的指针修改它(这就是为什么 LoadFileInResource() 函数实现将指针存储在一个 const char* 中)。你需要使用 BeginUpdateResource()UpdateResource()EndUpdateResource() 函数来进行操作。

我还有一个普遍的问题,在这里提出。您能否回答我的第二个问题,它与您的答案有关?就是如何拥有一个dll文件,其中包含您答案中的main函数中的代码。 - utvecklare
当程序退出时,系统会自动删除它们。所有程序在退出系统时都会释放资源吗?在可执行文件执行期间可能会发生内存泄漏和资源泄漏。因此,如果该程序加载了n个相同的资源,则会导致资源泄漏。 - Raindrop7
在资源文件的属性中,有“空终止字符串”。 - Laurie Stearn
我有一个Win32应用程序。 我可以知道在哪里可以找到资源文件,以及如何创建用户定义的资源文件吗? 我想在构建过程中加载一个XML文件。 文件大小为20MB。 - Programmer

-4

9
PE(+)文件已经具备存储自定义资源的能力,并且Windows构建工具已经具备了所需的一切。资源脚本语法已被记录,操作系统提供API以访问该数据。这是对另一个问题的回答。 - IInspectable

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接