你能提供一个例子,通过比较显示 ATL 的好处吗?
答案 0 :(得分:7)
听起来你想要一些ATL简化COM编程的具体例子;以下是我的想法。
CComObjectRootEx
:通过从CComObjectRootEx
派生您的COM类,您可以免费获得线程安全的引用计数。
CComCoClass
:此基类实现了实例化类的所有方法,包括客户端对组件使用IClassFactory
所需的CoGetClassObject
内容。
COM_INTERFACE_ENTRY
宏:ATL提供了一大堆宏,可以在BEGIN_COM_MAP
和END_COM_MAP
之间使用,您可以使用这些宏来实现IUnknown::QueryInterface
的内容正确的方式满足您的要求,无论它们是什么。
IDispatchImpl
:如果您希望脚本可以访问您的组件,则必须实现IDispatch
。 ATL提供了IDispatchImpl
类,这样就省去了自己实现它的麻烦。
CComPtr
/ CComQIPtr
:ATL提供了这些智能指针类,它们封装了对IUnknown::AddRef
,IUnknown::Release
和IUnknown::QueryInterface
的调用。使用它们将使您的代码更易于阅读,并且不易出现COM引用计数错误。
CComBSTR
/ CComVariant
:ATL提供了这些类,这降低了处理BSTR
和VARIANT
COM类型的复杂性。
答案 1 :(得分:3)
开发人员很懒惰,喜欢简单易用的东西,ATL旨在简化COM开发。
在大多数情况下,ATL负责处理COM开发的许多混乱细节,例如QueryInterface管理,引用计数和生命周期管理,以及COM支持的所有各种线程模型。它还为双接口,连接点,枚举器等内容提供内置支持。
如果您不使用ATL或类似的东西,您将编写更多代码。那将是不幸的;)
编辑:
我不打算在没有ATL的情况下编写任何COM代码,因为这样做非常可怕,但请查看:
http://www.codeproject.com/KB/COM/simplecomserver.aspx
下载该文件,然后查看simplecomserver项目下的以下文件:
registry.cpp
simplecomserverImpl.cpp
(约700行代码)
现在想象一下,您可以从CCoComClass派生一个类,而不是编写所有那些怪物,只需实现Name方法,然后执行此操作来处理类实例化和注册:
// Used to determine whether the DLL can be unloaded by OLE
STDAPI DllCanUnloadNow(void)
{
return _AtlModule.DllCanUnloadNow();
}
// Returns a class factory to create an object of the requested type
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
return _AtlModule.DllGetClassObject(rclsid, riid, ppv);
}
// DllRegisterServer - Adds entries to the system registry
STDAPI DllRegisterServer(void)
{
// registers object, typelib and all interfaces in typelib
HRESULT hr = _AtlModule.DllRegisterServer();
return hr;
}
// DllUnregisterServer - Removes entries from the system registry
STDAPI DllUnregisterServer(void)
{
HRESULT hr = _AtlModule.DllUnregisterServer();
return hr;
}