gpt4 book ai didi

c - 如何使用 VS11 在 C 程序中嵌入和使用资源文件?

转载 作者:行者123 更新时间:2023-12-02 22:40:12 24 4
gpt4 key购买 nike

这是我第一次尝试使用资源文件。我看到了很多适用于 C# 但不适用于 C 的答案。有什么建议吗?

最佳答案

假设您指的是 Sysinternals 和其他人使用 Microsoft Visual C 在程序的资源部分(例如 Sysinternals 的 Process Explorer)携带驱动程序或所需的 DLL(甚至程序本身的 x64 版本)的方法你可以使用这段代码:

BOOL ExtractResTo(HINSTANCE Instance, LPCTSTR BinResName, LPCTSTR NewPath, LPCTSTR ResType)
{
BOOL bResult = FALSE;
HRSRC hRsrc;
if(hRsrc = FindResource(HMODULE(Instance), BinResName, ResType))
{
HGLOBAL hGlob
if(HGLOBAL hGlob = LoadResource(Instance, hRsrc))
{
DWORD dwResSize = SizeofResource(Instance, hRsrc);
HANDLE hFileWrite = CreateFile(NewPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, 0);
if(hFileWrite != INVALID_HANDLE_VALUE)
__try
{
DWORD dwSizeWritten = 0;
bResult = (WriteFile(hFileWrite, LockResource(hGlob), dwResSize, &dwSizeWritten, NULL) && (dwSizeWritten == dwResSize));
}
__finally
{
CloseHandle(hFileWrite);
}
}
}
return bResult;
}

这会将资源类型 (ResType) 的给定资源 (BinResName) 从模块(例如 DLL)Instance 保存到文件 新路径。显然,如果您的 C 不理解 __try__finally,您将不得不相应地调整代码。

取自here (在 SIDT.rar 中)并针对 C 进行了调整。根据网站,该代码在自由 BSD 许可下。

现在,如果您想获取指向数据的指针 (ppRes) 及其大小 (pwdResSize):

BOOL GetResourcePointer(HINSTANCE Instance, LPCTSTR ResName, LPCTSTR ResType, LPVOID* ppRes, DWORD* pdwResSize)
{
// Check the pointers to which we want to write
if(ppRes && pdwResSize)
{
HRSRC hRsrc;
// Find the resource ResName of type ResType in the DLL/EXE described by Instance
if(hRsrc = FindResource((HMODULE)Instance, ResName, ResType))
{
HGLOBAL hGlob;
// Make sure it's in memory ...
if(hGlob = LoadResource(Instance, hRsrc))
{
// Now lock it to get a pointer
*ppRes = LockResource(hGlob);
// Also retrieve the size of the resource
*pdwResSize = SizeofResource(Instance, hRsrc);
// Return TRUE only if both succeeded
return (*ppRes && *pdwResSize);
}
}
}
// Failure means don't use the values in *ppRes and *pdwResSize
return FALSE;
}

这样调用:

LPVOID pResource;
DWORD pResourceSize;
if(GetResourcePointer(hInstance, _T("somename"), _T("sometype"), &pResource, &pResourceSize))
{
// use pResource and pResourceSize
// e.g. store into a string buffer or whatever you want to do with it ...
}

请注意,这也适用于具有整数 ID 的资源。您可以使用宏 IS_INTRESOURCE 检测到这些。

资源脚本,例如myresources.rc,本身很简单:

#include <winnt.rh>
"somename" "sometype" "path\to\file\to\embed"

RCDATA 而不是某种类型是一个合理的选择

#include <winnt.rh> // for RCDATA to be known to rc.exe
"somename" RCDATA "path\to\file\to\embed"

...在这种情况下,您可以将上述调用调整为:

GetResourcePointer(hInstance, _T("somename"), RT_RCDATA, &pResource, &pResourceSize)

使用上面的 GetResourcePointer 的完整示例。假设您有一个指针变量 char* buf 并且您知道您的资源是实际文本,那么您需要确保它在用作字符串时以零终止,仅此而已。

资源脚本:

#include <winnt.rh>

"test" RCDATA "Test.txt"

访问它的代码

char* buf = NULL;
LPVOID pResource;
DWORD pResourceSize;
if(GetResourcePointer(hInstance, _T("test"), RT_RCDATA, &pResource, &pResourceSize))
{
if(buf = calloc(pResourceSize+1, sizeof(char)))
{
memcpy(buf, pResource, pResourceSize);
// Now use buf
free(buf);
}
}

当然,除非您打算简单地链接一个 .res 文件,该文件通过将其传递给链接器命令行来工作。

关于c - 如何使用 VS11 在 C 程序中嵌入和使用资源文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10888988/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com