C++:从 dll 访问嵌入的资源

C++: Access embedded resource from dll

本文关键字:资源 访问 dll C++      更新时间:2023-10-16

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

IDR_TEMPLATE1           RCDATA                "areaTemplate.bin"

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

正如 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));
   }
}
首先使用

FindResource 或 FindResourceEx,然后使用 LoadResource 和 LockResource。

使用 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 的评论:

说明 负载资源的返回类型是 HGLOBAL,表示向后 兼容性,而不是因为该函数返回全局句柄 内存块。不要将此句柄传递给 GlobalLock 或 GlobalFree 功能。

没有"解锁资源"

或"免费资源"API。

说明 LockResource 返回的指针在模块之前有效 包含资源将被卸载。无需解锁 资源,因为系统在 创建它们的进程终止。

// 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));