C++ 如何在 VC++ 静态库中加载自定义二进制资源作为 dll 的一部分?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9240188/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 12:31:21  来源:igfitidea点击:

How to load a custom binary resource in a VC++ static library as part of a dll?

c++visual-studiovisual-c++resourcesstatic-libraries

提问by meissnersd

I have custom binary resources (animated cursors) that would like to store as resources in a static lib in Visual Studio C++. It turns out that custom binary resources will not get loaded by ::LoadCursor() or found by ::FindResource() if it is a custom resource and in a static library.

我有自定义二进制资源(动画游标),希望将其作为资源存储在 Visual Studio C++ 的静态库中。事实证明,如果自定义二进制资源是自定义资源且位于静态库中,则 ::LoadCursor() 将不会加载或由 ::FindResource() 找到自定义二进制资源。

This questiongives some work around.

这个问题提供了一些解决方法。

Following its advice, if I add the *.res file to an exe as a "Configuration Property->Linker->Additional Dependency" then the static library will be able to find the resource.

按照它的建议,如果我将 *.res 文件作为“配置属性->链接器->附加依赖项”添加到 exe 中,那么静态库将能够找到该资源。

BUT if the static library is part of a dll and I link it in as an Additional Dependency it is not found again!

但是,如果静态库是 dll 的一部分,并且我将其作为附加依赖项链接,则不会再次找到它!

How can I link the resources in a dll?

如何链接dll中的资源?

Or just make the binary be found in the static lib? The methods in the question are pretty cumbersome.

或者只是在静态库中找到二进制文件?问题中的方法非常繁琐。

回答by LihO

In Add Resource dialog click Import, select "All Files (.)" so that it allows you to import file of any type, and then just select the file you want there. When Custom Resource Type dialog pops up, type RCDATA into "Resource type" field.

在“添加资源”对话框中单击“导入”,选择“所有文件 ( .)”,以便它允许您导入任何类型的文件,然后只需选择您想要的文件即可。当自定义资源类型对话框弹出时,在“资源类型”字段中输入 RCDATA。

If you open .rc file, you will see something like this:

如果您打开 .rc 文件,您将看到如下内容:

/////////////////////////////////////////////////////////////////////////////
//
// RCDATA
//

IDR_RCDATA1          RCDATA               "myfile.whatever"

and it will generate resource.h with following line:

它将使用以下行生成 resource.h:

#define IDR_RCDATA1                  101

In code you access it like this:

在代码中,您可以像这样访问它:

#include "resource.h"
#include <windows.h>

int main(int argc, char* argv[])
{
    HRSRC myResource = ::FindResource(NULL, MAKEINTRESOURCE(IDR_RCDATA1), RT_RCDATA);
    HGLOBAL myResourceData = ::LoadResource(NULL, myResource);
    void* pMyBinaryData = ::LockResource(myResourceData);
    return 0;
}

where pMyBinaryData is pointer to first byte of this executable. For more information visit Resource Functions

其中 pMyBinaryData 是指向此可执行文件的第一个字节的指针。有关更多信息,请访问 资源函数

Here's an example how you would save binary resource like this on disk:

这是一个如何在磁盘上保存这样的二进制资源的示例:

#include "resource.h"
#include <windows.h>
#include <fstream>

int main(int argc, char* argv[])
{
    HRSRC myResource = ::FindResource(NULL, MAKEINTRESOURCE(IDR_RCDATA1), RT_RCDATA);
    unsigned int myResourceSize = ::SizeofResource(NULL, myResource);
    HGLOBAL myResourceData = ::LoadResource(NULL, myResource);
    void* pMyBinaryData = ::LockResource(myResourceData);

    std::ofstream f("C:\x.bin", std::ios::out | std::ios::binary);
    f.write((char*)pMyBinaryData, myResourceSize);
    f.close();

    return 0;
}

When you build project with resource like that, this resource will become part of your program (dll).

当您使用这样的资源构建项目时,该资源将成为您的程序 (dll) 的一部分。

回答by Ralph Erdt

The Problem of @LihO answer is:

@LihO 答案的问题是:

The first parameter of FindResourceis the ModuleID of the Module containing the resources. If this is set to NULLthe function will search in created process (.exe), not the DLL.

FindResource的第一个参数是包含资源的模块的 ModuleID。如果将其设置为NULL,该函数将在创建的进程 (.exe) 中搜索,而不是在 DLL 中搜索。

But how to get the HMODULE insinde a static LIB?

但是如何在静态 LIB 中获取 HMODULE 呢?

  • add a function / parameter, which will get the HMODULE from the DLL. The HMODULE / HINSTANCE (is the same) can be retrieved in DLLMain.
  • Try this GetCurrentModule
  • 添加一个函数/参数,它将从 DLL 中获取 HMODULE。可以在DLLMain 中检索 HMODULE / HINSTANCE(相同)。
  • 试试这个GetCurrentModule

Edit:

编辑:

See also: Add lib resource to a library

另请参阅:将 lib 资源添加到库

回答by Michal Pokluda

In case you use dll using MFC (and CWinApp), you can obtain the HMODULE from CWinApp.

如果您使用 MFC(和 CWinApp)使用 dll,您可以从 CWinApp 获取 HMODULE。

extern MyDllApp theApp;
HMODULE module = (HMODULE)theApp.m_hInstance;
HRSRC myResource = ::FindResource(module,
            MAKEINTRESOURCE(IDR_FILE_RESOURCE), _T("GROUP_NAME"));

If you supply NULLin FindResource, application won't find your resource.

如果您NULL在 FindResource 中提供,应用程序将找不到您的资源。