在VC编程中,当我们在操作资源中的声音、图片等一些资源时,都要用到进程的HINSANCE。不过在DLL中经常我们获取的HINSANCE不为空,但是使用的时候却获取不到资源,本文讨论的就是HINSTANCE获取的问题。
在MFC的exe程序中通常AfxGetInstanceHandle()就可以获取应用程序的实例句柄,非常简单,也可以使用GetModuleHandle()直接获取。这个就不细说了。下面主要讲一下在DLL中如何获取当前HINSTANCE。
考虑在DLL中以下两句代码:
在MFC的exe程序中通常AfxGetInstanceHandle()就可以获取应用程序的实例句柄,非常简单,也可以使用GetModuleHandle()直接获取。这个就不细说了。下面主要讲一下在DLL中如何获取当前HINSTANCE。
考虑在DLL中以下两句代码:
HINSTANCE hInst = GetModuleHandle();
hsrc = FindResource( hInst , MAKEINTRESOURCE(dwRID), (LPCTSTR)"wav ");
DWORD dwError = GetLastError();
我们会发现dwError返回1813错误,也就是取不到资源,但是GetModuleHandle 函数执行成功了,hInst也并不为空。为什么呢?仔细研究GetModuleHandle()函数发现,其实它还能带参数,我们将第一句改成:
HINSTANCE hInst = GetModuleHandle( “dll路径“);
这时候就不会出错了。原来在DLL中获取HINSTANCE,需要将DLL路径作为参数传进去。直接使GetModuleHandle()获取的是当前DLL所在exe程序的HINSTANCE。问题到这儿就解决了。可是如果我们并不知道DLL路径呢?如我们软件给用户使用的时候,每个用户可以选在不同的安装路径,我们用这个方法就没办法获取DLL进程实例句柄了。那么有没有其他方法可以获取呢?DLL在运行的时候, 内存中一定有它的相关信息, 我们能直接从内存中来获取其HINSTANCE不?事实上是可以的,下面为获取DLL的HINSTANCE函数:
获取dll模块句柄
HMODULE GetCurrentModule()
{
#if _MSC_VER < 1300 // earlier than .NET compiler (VC 6.0)
// Here's a trick that will get you the handle of the module
// you're running in without any a-priori knowledge:
MEMORY_BASIC_INFORMATION mbi;
static int dummy;
VirtualQuery( &dummy, &mbi, sizeof(mbi) );
return reinterpret_cast<HMODULE>(mbi.AllocationBase);
#else
// from ATL 7.0 sources
return reinterpret_cast<HMODULE>(&__ImageBase);
#endif
}
上面这个函数就可以直接返回当前DLL实例句柄,这个方法也就不需要考虑DLL路径问题了。
获取进程句柄实例并不止上述几种方法,比如还可以根据进程名或者进程ID获取,这儿就不用再一一细述,但是编码中最常用的还是本文所描述的这几种方法。
DWORD dwError = GetLastError();
我们会发现dwError返回1813错误,也就是取不到资源,但是GetModuleHandle 函数执行成功了,hInst也并不为空。为什么呢?仔细研究GetModuleHandle()函数发现,其实它还能带参数,我们将第一句改成:
HINSTANCE hInst = GetModuleHandle( “dll路径“);
这时候就不会出错了。原来在DLL中获取HINSTANCE,需要将DLL路径作为参数传进去。直接使GetModuleHandle()获取的是当前DLL所在exe程序的HINSTANCE。问题到这儿就解决了。可是如果我们并不知道DLL路径呢?如我们软件给用户使用的时候,每个用户可以选在不同的安装路径,我们用这个方法就没办法获取DLL进程实例句柄了。那么有没有其他方法可以获取呢?DLL在运行的时候, 内存中一定有它的相关信息, 我们能直接从内存中来获取其HINSTANCE不?事实上是可以的,下面为获取DLL的HINSTANCE函数:
获取dll模块句柄
HMODULE GetCurrentModule()
{
#if _MSC_VER < 1300 // earlier than .NET compiler (VC 6.0)
// Here's a trick that will get you the handle of the module
// you're running in without any a-priori knowledge:
MEMORY_BASIC_INFORMATION mbi;
static int dummy;
VirtualQuery( &dummy, &mbi, sizeof(mbi) );
return reinterpret_cast<HMODULE>(mbi.AllocationBase);
#else
// from ATL 7.0 sources
return reinterpret_cast<HMODULE>(&__ImageBase);
#endif
}
上面这个函数就可以直接返回当前DLL实例句柄,这个方法也就不需要考虑DLL路径问题了。
获取进程句柄实例并不止上述几种方法,比如还可以根据进程名或者进程ID获取,这儿就不用再一一细述,但是编码中最常用的还是本文所描述的这几种方法。