【问题标题】:COM Objects in Direct3DDirect3D 中的 COM 对象
【发布时间】:2021-02-21 08:25:00
【问题描述】:

如 Microsoft 文档中所述,有两种创建 COM 对象的方法:

  1. 实现该对象的模块可能会提供一个专门用于创建该对象实例的函数。
  2. 另外,COM 提供了一个名为 CoCreateInstance 的通用创建函数。

在 direct3D 中,您可以使用第一种方法创建对象,就像使用 D3D11CreateDevice() 但是你如何通过第二种方法做到这一点。也许你需要我没有找到的CLSID_D3D11CreateDevice。是否有任何库要包含或者可能无法通过第二种方法创建。 我也很想知道是否有办法查看 COM 对象以及它们实现了哪些接口。

【问题讨论】:

  • 不可能使用 2) 创建 DirectX 对象。通常,您提供一种方法或另一种方法,而不是两者都提供。官方实现的接口在文档中。尽管有一些机制可以发现一些元数据,但 DirectX 并没有实现它。它有时被称为“轻量级”COM:您有带有 vtable/IUnknown 派生的对象,仅此而已。
  • 程序员会停止认为这与 COM 有任何关系,这对他们自己有利。 DirectX 使用更通用的interface-based programming model,它避免了与 COM 相关的所有 DLL Hell 问题。 C++ 中常见的 PIMPL 模式非常相似。您必须使用专用的工厂函数,并将其链接到您的程序中,不能让 COM 管道为您找到依赖项。后果是一样的,你只有一个指针,什么都看不到。

标签: winapi com direct3d


【解决方案1】:

DirectX API 不是“真正的 COM”。这些 API 派生自 IUnknown 用于引用计数和版本控制的多态接口,但它们不遵循 COM 对象的所有其他规则。生命周期规则也为“子”对象修改,DirectX API 仅支持COINIT_MULTITHREADED

这是一种非正式地称为“COM lite”或“nano-COM”的设计模式。

  • 对象是使用 Win32“平面”工厂函数创建的
  • 对象一般只支持IUnknown、主界面和主界面的派生版本
  • 接口上的方法可以返回voidHRESULT
  • 并非所有方法都需要线程安全
  • 它们不支持 COM 聚合
  • 作为参数的接口指针不支持客户端提供的实现

Direct2D/DirectWrite 和 Windows Imaging Component (WIC) 支持 CoCreateInstance 就像最初的 XAudio2 for Windows 版本 2.7 和旧版 XACT 一样。否则,“DirectX”组件不支持基于注册表或基于清单的创建。

此模式提供了稳定的“应用程序二进制接口 (ABI)”,并很好地映射到纯虚拟类的 C++ 单一继承。它提供了一种简单的方法来扩展新版本以添加方法和生命周期管理的引用计数。生成的 API 通常与 IID_PPV_ARGS 宏以及 COM 智能指针(如 Microsoft::WRL::ComPtrwinrt::com_ptr 或较旧的 ATL CComPtr)兼容。

Microsoft Docs: Programming DirectX with COM

DirectX 的较新版本(如 DirectX 12)采用了旧版本中未使用的“强类型位掩码”。见this blog post

虽然过去 DirectX“COM lite”API 通过宏提供 C 支持,但最新的指导是仅支持 C++ 并利用 C++11 功能,如强类型枚举(又名scoped enumerations)。您会在DXCore 界面中看到这一点。

【讨论】:

  • 我做 COM 有一段时间了,从来没有听说过“com lite”或“nano com”。谷歌也没有。但我同意用一个更好的术语来帮助程序员(如 OP)不会受到伤害。
  • XAudio2 不需要 COM 吗?
  • XAudio 2.7 及更早版本需要 COM。 XAudio 2.8 (Windows 8) 和 XAudio 2.9 (Windows 10) 不使用CoCreateInstance。对于 Windows 7,您现在应该通过XAudio2Redist 使用 XAudio 2.9,因为旧版 XAudio 2.7 有许多已知错误,并且仍然取决于已弃用的 DirectSetup 部署。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-15
  • 2017-08-17
  • 2012-08-24
  • 2018-04-27
  • 2011-09-10
  • 2011-07-25
  • 1970-01-01
相关资源
最近更新 更多