Can you provide an example that through comparation shows the benifit of ATL?
Developers are lazy and prefer things that are easy over things that are hard, and ATL was designed to make COM development easier.
In most cases ATL takes care of many of the messy details of COM development, like QueryInterface management, reference counting and lifetime management, and all of the various threading models that COM supports. It also provides built-in support for things like dual-interfaces, connection points, enumerators, etc.
If you don't use ATL, or something like it, you'll be writing a lot more code. That would be unfortunate ;)
Edit:
I'm not going to write any COM code without ATL for an example because it is so horrendous to do so, but check out this:
http://www.codeproject.com/KB/COM/simplecomserver.aspx
Download that and then look at the following files under the simplecomserver project:
registry.cpp
simplecomserverImpl.cpp
(around 700 lines of code)
Now imagine that instead of writing all of that monstrosity, you could derive a class from CCoComClass and just implement the Name method, and then do this to handle class instantiation and registration:
// 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;
}
It sounds like you want some concrete examples of where ATL simplifies COM programming; the following are what occurred to me.
CComObjectRootEx
: By deriving your COM classes fromCComObjectRootEx
, you get thread-safe reference-counting free of charge.CComCoClass
: This base class implements all the methods for instantiating your class, including theIClassFactory
stuff that is required for clients to useCoGetClassObject
with your component.COM_INTERFACE_ENTRY
macros: ATL offers a whole bunch of macros to use betweenBEGIN_COM_MAP
andEND_COM_MAP
, which you can use to implement the guts ofIUnknown::QueryInterface
in the correct manner for your requirements, whatever they may be.IDispatchImpl
: If you want your components to be accessible to script, you must implementIDispatch
. ATL provides theIDispatchImpl
class, which saves the hassle of implementing it yourself.CComPtr
/CComQIPtr
: ATL provides these smart pointer classes, which encapsulate calls toIUnknown::AddRef
,IUnknown::Release
andIUnknown::QueryInterface
. Using them will make your code easier to read and less prone to COM reference-counting bugs.CComBSTR
/CComVariant
: ATL provides these classes, which reduce the complexity of dealing with theBSTR
andVARIANT
COM types.