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