5

我有一个 c++ dll 项目,其中我通过“resource.rc”文件嵌入了一些原始数据。

IDR_TEMPLATE1           RCDATA                "areaTemplate.bin"

现在我想从 dll 中访问“areaTemplate.bin”文件的数据。如何读取字节数组中“areaTemplate.bin”的内容?

4

3 回答 3

3

正如 Manuell 所说,您使用FindResource()LoadResource()可能还有 LockResource()SizeofResource()

我碰巧有一些代码可以提取资源并将其写入文件,这可能有助于您理解相关 API。

void WriteResourceToFile(
   HANDLE hFile,
   const _tstring &resourceName,
   const _tstring &resourceType,
   HMODULE hModule)
{
   HRSRC hResource = ::FindResource(
      hModule,
      resourceName.c_str(),
      resourceType.c_str());

   if (!hResource)
   {
      const DWORD lastError = ::GetLastError();

      throw CWin32Exception(
         _T("WriteResourceToFile() - FindResource"),
         lastError);
   }

   HGLOBAL hGlobal = ::LoadResource(hModule, hResource);

   if (!hGlobal)
   {
      const DWORD lastError = ::GetLastError();

      throw CWin32Exception(
         _T("WriteResourceToFile() - LoadResource"),
         lastError);
   }

   void *pData = ::LockResource(hGlobal);

   if (!pData)
   {
      const DWORD lastError = ::GetLastError();

      throw CWin32Exception(
         _T("WriteResourceToFile() - LockResource"),
         lastError);
   }

   const DWORD bytes = ::SizeofResource(hModule, hResource);

   DWORD bytesWritten = 0;

   if (!::WriteFile(hFile, pData, bytes, &bytesWritten, 0))
   {
      const DWORD lastError = ::GetLastError();

      throw CWin32Exception(
         _T("WriteResourceToFile() - WriteFile"),
         lastError);
   }

   if (bytesWritten != bytes)
   {
      throw CWin32Exception(
         _T("WriteResourceToFile() - WriteFile"),
         _T("Wrote less bytes (") + ToString(bytesWritten) +
         _T("( than expected: ") + ToString(bytes));
   }
}
于 2013-11-13T11:50:02.547 回答
2

首先使用FindResourceFindResourceEx,然后使用LoadResourceLockResource

使用SizeofResource获取数据的大小。

代码:

HMODULE g_hModDll;

[...]

HRSRC hRscr = FindResource( g_hModDll, MAKEINTRESOURCE( IDR_TEMPLATE1 ),
                            MAKEINTRESOURCE( RT_RCDATA ) );
if ( hRscr ) {
    HGLOBAL hgRscr = LoadResource( g_hModDll, hRscr );
    if ( hgRscr ) {
        PVOID pRscr = LockResource( hgRscr );
        DWORD cbRscr = SizeofResource( g_hModDll, hRscr );
    }
}

请务必阅读以下有关 LoadResource 的注释:

备注LoadResource 的返回类型是 HGLOBAL 是为了向后兼容,而不是因为函数返回全局内存块的句柄。不要将此句柄传递给 GlobalLock 或 GlobalFree 函数。

没有“解锁资源”或“免费资源”API。

备注LockResource 返回的指针在卸载包含该资源的模块之前有效。无需解锁资源,因为系统会在创建它们的进程终止时自动删除它们。

于 2013-11-13T11:42:17.087 回答
0
// Determine the module handle of your DLL by locating a function
// you know resides in that DLL
HMODULE hModule;
GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
        (LPCSTR)&myDLLfuncName, &hModule)

HRSRC hRscr = FindResource(hModule, MAKEINTRESOURCE(IDR_TEMPLATE1),
                           MAKEINTRESOURCE(RT_RCDATA));
于 2016-07-06T05:20:04.843 回答