2

As mentioned in Microsoft documentation there are two ways to create COM objects:

  1. The module that implements the object might provide a function specifically designed to create instances of that object.
  2. Alternatively, COM provides a generic creation function named CoCreateInstance.

In direct3D you can use first method to create Objects like you use D3D11CreateDevice() but how you do this by the second method.maybe you need CLSID_D3D11CreateDevice which I didn't find.Is there any library to include or maybe it's impossible to create by the second way. Also I really like to know if there is a way to see COM objects and what interfaces they implement.

  • It's impossible to use 2) to create DirectX objects. In general, you provide one method or the other, not both. Interfaces officially implemented are in the documentation. Although there are some mechanisms to discover some metadata, DirectX doesn't implement it. It's sometimes called "lightweight" COM: you have objects with a vtable/IUnknown derivates and that's about it. – Simon Mourier Nov 09 '20 at 12:13
  • Programmers will do themselves a favor by stopping to think that this has anything to do with COM. DirectX uses a much more general [interface-based programming model](https://en.wikipedia.org/wiki/Interface-based_programming) that avoids all of the DLL Hell trouble that's associated with COM. The common PIMPL pattern in C++ is pretty similar. You must use the dedicated factory function, and link it into your program, no option to let the COM plumbing find the dependencies for you. Consequences are the same, you only have a pointer and can't see anything. – Hans Passant Nov 09 '20 at 12:34

1 Answers1

3

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.

Chuck Walbourn
  • 38,259
  • 2
  • 58
  • 81
  • I've been doing COM for a while, never heard of "com lite" or "nano com". Google didn't either. But I agree that a better term for it to help programmers (like the OP) won't hurt. – Hans Passant Nov 09 '20 at 22:19
  • Doesn't XAudio2 require COM? – Acorn Nov 10 '20 at 10:15
  • XAudio 2.7 and earlier required COM. XAudio 2.8 (Windows 8) and XAudio 2.9 (Windows 10) do not use ``CoCreateInstance``. For Windows 7, you should use XAudio 2.9 via [XAudio2Redist](https://aka.ms/xaudio2redist) these days as legacy XAudio 2.7 has a number of known bugs as well as still depending on the deprecated DirectSetup deployment. – Chuck Walbourn Nov 10 '20 at 19:02