在本机 Windows 应用程序的资源中嵌入文本文件

Posted

技术标签:

【中文标题】在本机 Windows 应用程序的资源中嵌入文本文件【英文标题】:Embed Text File in a Resource in a native Windows Application 【发布时间】:2010-05-29 00:42:39 【问题描述】:

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

【问题讨论】:

【参考方案1】:

由于您正在开发本机 Windows 应用程序,因此您要做的是创建一个用户定义的资源,以将文本文件的内容嵌入到已编译的资源中。

用户定义资源的格式是documented on MSDN,the functions for loading it也是。

您将文本文件嵌入到这样的资源文件中:

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() 函数来执行此操作。

【讨论】:

我还有一个更普遍的疑问问here。您能否回答我与您的回答相关的第二个问题?只是如何拥有一个 dll 文件,该文件具有包含答案中 main 中的代码的功能。 " 程序退出时系统会自动删除" 难道所有程序退出系统时都没有资源吗?内存泄漏和资源泄漏发生在可执行文件的执行过程中。因此,如果该程序加载 n 个相同的资源,它将导致资源泄漏。 在资源文件的属性中有“Null Terminate Strings” 我有一个 win32 应用程序。我可以知道在哪里可以找到资源文件以及如何创建用户定义的资源文件吗?我想在构建过程中加载一个 xml 文件。文件大小为 20MB。【参考方案2】:

您可以使用xxd(来自 linux 机器或可能来自 cygwin)生成 .h/.cc 文件的数据。

有很多堆栈溢出问题对此进行了详细扩展:

How can I get the contents of a file at build time into my c string “#include” a text file in a C program as a char[]

【讨论】:

-1 PE(+) 文件已经能够存储自定义资源,Windows 构建工具拥有您需要的一切。资源脚本语法已记录在案,操作系统提供了用于访问该数据的 API。这个答案是另一个问题的答案。

以上是关于在本机 Windows 应用程序的资源中嵌入文本文件的主要内容,如果未能解决你的问题,请参考以下文章

MobileFirst:将文件从本机资源文件夹复制到 Android 环境中的本机文件夹

测试驱动的嵌入式开发 001:VSCode + CMake + CppUTest 环境搭建

测试驱动的嵌入式开发 001:VSCode + CMake + CppUTest 环境搭建

如何启动windows资源管理器

论文泛读107隐藏在中文词嵌入背后的性别偏见:以中文形容词为例

测试驱动开发 001:VSCode + CMake + CppUTest 环境搭建