通过编程实践可以发现,如果通过ATL向导生成的COM,自动会生成DllRegisterServer及DllUnregisterServer函数,可供regsvr32等调用进行
注册与反注册。而如果通过普通的DLL向导并选择Automation支持,则只会自动生成DllRegisterServer,而没有DllUnregisterServer接口,因
此需要手工添加一个DllUnregisterServer函数。当试图在此函数中调用COleObjectFactory::UnregisterAll()进行反注册时,跟踪源代码可知
最终只是简单地返回了TRUE,所以根本没有反注册。
为了能够仿ATL实现COM的反注册,需要研究ATL注册/反注册源代码:
STDAPI DllRegisterServer(void)
{
// registers object, typelib and all interfaces in typelib
return _Module.RegisterServer(TRUE);
}
/
// DllUnregisterServer - Removes entries from the system registry
STDAPI DllUnregisterServer(void)
{
return _Module.UnregisterServer(TRUE);
}
_Module为一个CComModule的全局对象,就类似于CXXXApp的全局对象,上面两个函数是CComModule的成员函数,如下:
HRESULT RegisterServer(BOOL bRegTypeLib = FALSE, const CLSID* pCLSID = NULL)
{
return AtlModuleRegisterServer(this, bRegTypeLib, pCLSID);
}
HRESULT UnregisterServer(BOOL bUnRegTypeLib, const CLSID* pCLSID = NULL)
{
return AtlModuleUnregisterServerEx(this, bUnRegTypeLib, pCLSID);
}
由于注册与反注册是类似的,下面以普通支持自动化的DLL中没有的反注册功能为例
ATLINLINE ATLAPI AtlModuleUnregisterServerEx(_ATL_MODULE* pM, BOOL bUnRegTypeLib, const CLSID* pCLSID)
{
ATLASSERT(pM != NULL);
if (pM == NULL)
return E_INVALIDARG;
ATLASSERT(pM->m_hInst != NULL);
ATLASSERT(pM->m_pObjMap != NULL);
_ATL_OBJMAP_ENTRY* pEntry = pM->m_pObjMap;
for (;pEntry->pclsid != NULL; pEntry = _NextObjectMapEntry(pM, pEntry))
{
if (pCLSID == NULL)
{
if (pEntry->pfnGetObjectDescription != NULL
&& pEntry->pfnGetObjectDescription() != NULL)
continue;
}