DirectX APIs are not "true COM". These APIs derive from IUnknown
for reference counting and polymorphic interfaces for versioning, but they do not follow all the other rules of COM objects. The lifetime rules are also modified for "child" objects, and DirectX APIs only support COINIT_MULTITHREADED
.
This is a design pattern known informally as "COM lite" or "nano-COM".
- Objects are created with a Win32 "flat" factory function
- Objects generally support only
IUnknown
, the main interface, and derived versions of the main interface
- Methods on interfaces can return
void
or HRESULT
- Not all methods need to be thread-safe
- They do not support COM aggregation
- Interface pointers as parameters do not support client-provided implementations
Direct2D/DirectWrite and Windows Imaging Component (WIC) support CoCreateInstance
as did did the original XAudio2 for Windows up to version 2.7 and legacy XACT. Otherwise, "DirectX" components do not support registry-based or manifest-based creation.
This pattern provides a stable "Application Binary Interface (ABI)" and maps well to C++ single-inheritance of pure-virtual classes. It provides an easy way to extend with new versions to add methods, and reference-counting for lifetime management. The resulting APIs are generally compatible with the IID_PPV_ARGS
macro as well as COM smart-pointers like Microsoft::WRL::ComPtr, winrt::com_ptr, or the older ATL CComPtr.
See Microsoft Docs: Programming DirectX with COM
More recent versions of DirectX like DirectX 12 have adopted "strongly-typed bitmasks" which were not used in older versions. See this blog post.
While historically the DirectX "COM lite" APIs have provided C support through macros, the most recent guidance is to just support C++ and make use of C++11 features like strongly-typed enumerations (a.k.a. scoped enumerations). You'll see this reflected in the DXCore interfaces.