FindResource在DLL中的正确用法

本文介绍了在DLL中使用FindResource函数的正确方法。作者详细解释了当使用NULL作为模块句柄时,该函数会尝试加载EXE而不是DLL中的资源。通过使用DLL实例句柄(theApp.m_hInstance),成功解决了资源加载问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

FindResource在DLL中的正确用法

场景

我在写MFC应用程序的时候,假设程序名字叫做MyApp。我在MyApp的resource.h文件中定义了一个资源的ID,如下所示

#define IDR_FILES_MYZIPFILE   3000

然后在相应的MyApp.rc文件中定义了这个资源ID所指向的资源的位置,如下:

IDR_FILES_MYZIPFILE   FILES             "res\\MyZip.zip"

然后我在编写我的程序的时候,我通过以下方式想要加载DLL中的资源,也就是上面所述的资源,代码如下:

HRSRC hRes = FindResource(NULL, MAKEINTRESOURCE(wResName), szResType);
if (NULL == hRes){
		DWORD dErrorCode = GetLastError();
		return FALSE;
	}

却发现我的MyApp程序找不到这个资源。因为调试代码的时候发现hRes,为空,并且dErrorCode返回1814。1814是一个Windows自己定义的错误号,其定义在WinError.h中,我把1814的错误解释贴出来:

//
// MessageId: ERROR_RESOURCE_NAME_NOT_FOUND
//
// MessageText:
//
// The specified resource name cannot be found in the image file.
//
#define ERROR_RESOURCE_NAME_NOT_FOUND    1814L

然后我就开始了我的面向google编程,打开chrome,搜索“FindResource调用失败”,查到的原因大致是一样的,即FindResource这个函数在exe中传入的第一个参数为NULL时,加载的是exe这个模块本身的资源(在exe程序对应的resource.h中定义,在exe程序对应的rc文件中指定资源位置),所以是能够找到的,但是在DLL中,传入第一个参数为NULL时,其加载的资源也是exe模块的资源,所以在dll中代码调用的是这个函数其实是去exe的资源文件中找对应的资源,如果没有找到就失败,返回NULL。这里 有一种情况即使资源号在exe中有,但是szResType不匹配是不是算没找到请读者自己验证。很显然我的目的是想加载DLL中的资源,于是上网搜了FindResource在DLL的正确用法,找到结果无外乎以下这种方式:
在这里插入图片描述
不知道别人对这种处理方法怎么看的,我的想法如下:

  • 第一、我猜想这里直接把路径写死应该是不对的,你怎么知道某个应用程序在调用你的dll的时候,二者的相对位置路径呢(当然我没有对此进行验证,有兴趣的自己验证)
  • 第二、FindResource函数的调用是作为你Dll的一部分,直接将Dll的名字写死在这里并不合适吧。假如某一天,另外一个编写应用程序的人调用了你的DLL,然后将其改名为另外一个名字,那么就悲催了,这时候是找得到还是找不到呢,读者自己验证,。

究其以上两点,我认为以上这种处理方式是有问题的,我是不会采用的。所以后面从FindResource的第一个参数着手,既然exe加载的是自己模块的句柄,那么我DLL的代码调用这个函数时不用exe的句柄,用自己的句柄不就好了,所以就想到了DLL程序自己有一个自己模块的句柄。

class CMyApp: public CWinApp
{
public:
	CMyApp();

// 重写
public:
	virtual BOOL InitInstance();

	DECLARE_MESSAGE_MAP()
	virtual int ExitInstance();

	ULONG_PTR GetGdiplusToken();
protected:
	GdiplusStartupInput		m_gdiplusStartupInput;
	ULONG_PTR				m_gdiplusToken;
};

extern CMyApp theApp;

theApp不就是代表DLL程序自己本身吗,那么找其内部的成员变量,应该就能找到这个代表本身的值: theApp.m_hInstance
然后我的调用如下:

HRSRC hRes = FindResource(theApp.m_hInstance, MAKEINTRESOURCE(wResName), szResType);

然后运行程序,资源果然被加载进来了。
以上是我对“FindResource在DLL中的正确用法”的一点浅薄看法,既做个人记录,也为大家提供参考,认为我所说有问题的,请告知我,文明留言。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值