Lesson 7 | In-process COM servers and DllGetClassObject |
Objective | Describe what DllGetClassObject does. |
DllGetClassObject
:
STDAPI DllGetClassObject(const CLSID& rclsid, const IID& riid, VOID ** ppv);
VOID **
output parameter.
CoGetClassObject
DllGetClassObject
. We will discuss CoGetClassObject
later in this module. COM imposes itself as an intermediary between the client and the server. This is called Local/Remote Transparency because the details of how the server is activated, connecting the client and server, and of how a client's COM call is routed to server is transparent to both the client and the server. The code to make an in-process call looks just like the code that makes a remote call. As needed, COM will handle the details involved with managing local and remote connections between the client and the server.
CoCreateInstanceEx
IID_IClassFactory
. If the server supports the requested COM object, it creates a class factory and calls QueryInterface
in the new class factory. The following code demonstrates an implementation of DllGetClassObject
.
// CClassFactory01 implements // O1's class factory struct CClassFactory01 : public IClassFactory { ULONG m_refcnt; // IUnknown Methods HRESULT QueryInterface(const IID& riid, VOID **ppv) { ... } ULONG AddRef() { ... } ULONG Release() { ... } // IClassFactory Methods HRESULT CreateInstance(IUnknown *pOuter, const IID& iid, VOID **ppv) { ... } HRESULT LockServer(BOOL fLock) { ... } }; STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) { HRESULT hr; if (CLSID_O1 == rclsid) { CClassFactory01 *pcfO1 = new CClassFactory01(); hr = pcfO1->QueryInterface(riid, ppv); if (FAILED(hr)) { delete pcfO1; return hr; } } else return CLASS_E_CLASSNOTAVAILABLE; return S_OK; }
The CClassFactory01
struct inherits from IClassFactory
, which is a standard interface in the COM framework that provides methods for creating class objects and controlling object lifetimes. The class factory is a fundamental part of the COM architecture, as it is used to create instances of a COM class when requested by a client.
This is a reference count used for managing the lifetime of the class factory object. COM uses reference counting to manage object lifetimes, and this counter is incremented or decremented as clients acquire or release references to the object.
This method is part of the IUnknown
interface and is used to obtain pointers to the supported interfaces on an object. It takes the interface identifier (IID
) and a pointer to hold the interface pointer. The implementation will check if the requested interface is supported and return the appropriate interface if available.
Increases the reference count (m_refcnt
) when a client holds a new reference to the object. This ensures the object remains alive while references exist.
Decreases the reference count and deletes the object when the count reaches zero, freeing resources.
This method is responsible for creating an instance of the COM class O1
. It takes a pointer to the controlling IUnknown
(if the object is being aggregated), the interface identifier (iid
), and a pointer to receive the created instance. The method would typically initialize the new object and return it to the client.
Used to lock or unlock the server, ensuring that the DLL containing the class factory does not unload until explicitly released. This method is useful for keeping the COM server loaded when it is expected to be frequently used.
REFCLSID rclsid
: The class ID of the object to be created. The function checks if the requested CLSID
matches the CLSID_O1
(the class ID for O1
).
REFIID riid
: The interface ID requested on the class factory.
LPVOID *ppv
: A pointer to receive the class factory interface.
rclsid
matches CLSID_O1
, a new instance of CClassFactory01
is created.QueryInterface
method is called to get the requested interface on the class factory.QueryInterface
fails, the created class factory is deleted, and an error is returned.rclsid
does not match CLSID_O1
, the function returns CLASS_E_CLASSNOTAVAILABLE
, indicating that the requested class is not available.S_OK
.