【发布时间】:2011-02-25 08:56:52
【问题描述】:
我有一个 C++ Windows 程序。我有一个包含一些数据的文本文件。目前,文本文件是一个单独的文件,在运行时加载并解析。如何将它作为资源嵌入到二进制文件中?
【问题讨论】:
标签: c++ c winapi resources text-files
我有一个 C++ Windows 程序。我有一个包含一些数据的文本文件。目前,文本文件是一个单独的文件,在运行时加载并解析。如何将它作为资源嵌入到二进制文件中?
【问题讨论】:
标签: c++ c winapi resources text-files
由于您正在开发本机 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() 函数来执行此操作。
【讨论】:
您可以使用xxd(来自 linux 机器或可能来自 cygwin)生成 .h/.cc 文件的数据。
有很多堆栈溢出问题对此进行了详细扩展:
【讨论】: