LoadLibrary/LoadLibraryEx用来加载DLL到自己的进程空间,使用完用FreeLibrary释放,一般使用方式如下:
HINSTANCE hInstRich
=
::LoadLibrary(CRichEditCtrl::GetLibraryName());
ATLASSERT(hInstRich
!=
NULL);
::FreeLibrary(hInstRich);
若使用过程中遇到跳转语句,即使不忘记 FreeLibrary,代码也会变得相当难看.一种优雅的封装方式如下(原理同智能指针):
class
CLoadLibrary
{
public
:
HINSTANCE m_hInst;
CLoadLibrary(HINSTANCE hInst
=
NULL) : m_hInst(hInst)
{
}
CLoadLibrary(LPCTSTR pstrFileName) : m_hInst(NULL)
{
Load(pstrFileName);
}
~
CLoadLibrary()
{
Free();
}
BOOL Load(LPCTSTR pstrFileName, DWORD dwFlags
=
0
)
{
ATLASSERT(
!
::IsBadStringPtr(pstrFileName, MAX_PATH));
Free();
m_hInst
=
::LoadLibraryEx(pstrFileName, NULL, dwFlags);
return
m_hInst
!=
NULL;
}
void
Free()
{
if
( IsLoaded() ) {
::FreeLibrary(m_hInst);
m_hInst
=
NULL;
}
}
HINSTANCE Detach()
{
HINSTANCE hInst
=
m_hInst;
m_hInst
=
NULL;
return
hInst;
}
BOOL IsLoaded()
const
{
return
m_hInst
!=
NULL;
}
FARPROC GetProcAddress(LPCSTR pszFuncName)
const
{
ATLASSERT(
!
::IsBadStringPtrA(pszFuncName,
-
1
));
ATLASSERT(IsLoaded());
return
::GetProcAddress(m_hInst, pszFuncName);
}
BOOL GetFileName(LPTSTR pstrFilename, DWORD cchMax
=
MAX_PATH)
const
{
ATLASSERT(IsLoaded());
return
::GetModuleFileName(m_hInst, pstrFilename, cchMax);
}
operator
HINSTANCE()
const
{
return
m_hInst;
}
};
应用这个封装,上述示例即可这样写:
CLoadLibrary loadEditDll( CRichEditCtrl::GetLibraryName() );
ATLASSERT( loadEditDll.IsLoaded() );