Label: DllGetClassObject
DllGetClassObject function is a core entry point of a COM DLL server. This function is used by the COM runtime to obtain a class factory, which is then responsible for creating object instances.
Unlike regular APIs, DllGetClassObject is not called directly by application code. Instead, COM invokes DllGetClassObject when a client requests an object by its CLSID, for example via CoCreateInstance.
Why DllGetClassObject function exists
A COM object cannot be instantiated like a regular C++ class from another module. The client knows the interface, CLSID, and IID; however, it does not know how the object is implemented inside the DLL.
Because of this separation, COM needs an entry point that hides implementation details. DllGetClassObjectfunction fulfills this role: it receives the class identifier, checks whether the DLL supports it, and returns a class factory—typically an implementation of IClassFactory.
After that, COM proceeds with object creation. In particular, it calls CreateInstance on the factory returned by DllGetClassObject.
The typical signature is:
STDAPI DllGetClassObject(
REFCLSID rclsid,
REFIID riid,
LPVOID* ppv
);
Here, rclsid specifies which COM class is requested. Meanwhile, riid defines the interface that should be returned—most often IID_IClassFactory. Finally, the resulting pointer is written to ppv.
Relation to CoCreateInstance
When client code calls:
CoCreateInstance(
clsid,
nullptr,
CLSCTX_INPROC_SERVER,
iid,
&object
);
COM performs several steps behind the scenes. First, it locates the DLL using system registration. Then, it loads the library and resolves the DllGetClassObject export. After that, COM calls DllGetClassObject to obtain the class factory and, finally, creates the object through it.
Therefore, CoCreateInstance acts as a high-level API, while DllGetClassObject serves as the internal entry point every COM DLL server must provide.
What a typical implementation does
In a minimal implementation, DllGetClassObject checks the requested CLSID. If the class is supported, it creates or retrieves a class factory. Otherwise, it returns an error.
Once the factory is available, QueryInterface is used to obtain the requested interface.
STDAPI DllGetClassObject(
REFCLSID rclsid,
REFIID riid,
LPVOID* ppv
)
{
if (ppv == nullptr)
return E_POINTER;
*ppv = nullptr;
if (rclsid != CLSID_MyObject)
return CLASS_E_CLASSNOTAVAILABLE;
auto factory = new MyClassFactory();
HRESULT hr = factory->QueryInterface(riid, ppv);
factory->Release();
return hr;
}
In real-world scenarios, additional care is required. For example, reference counting must be strictly correct, and error paths must be handled consistently. Moreover, the implementation should cooperate with DllCanUnloadNow so that COM can safely unload the DLL.
Common pitfalls
A common mistake is assuming that DllGetClassObject creates the final object. In reality, DllGetClassObject usually returns a class factory, not the object itself.
Another issue is incorrect handling of ppv. It must be validated, explicitly set to nullptr on failure, and assigned only on success.
Finally, developers sometimes confuse CLSID and IID. While CLSID identifies the class to create, IID specifies the interface to retrieve.
Summary
Overall, DllGetClassObject is a required entry point for any COM DLL server. It connects COM registration, DLL loading, class factories, and object creation into a single flow.
As a result, even though client code typically relies on CoCreateInstance, the actual creation process depends entirely on DllGetClassObject implemented inside the DLL.