首页 > 解决方案 > 删除智能指针

问题描述

我正在为 CLR 项目测试一些代码示例。如果不使用智能指针,这段代码等效于什么?

Microsoft::WRL::ComPtr<ID3D11Device1> m_d3dDevice;
Microsoft::WRL::ComPtr<IDXGIDevice1> dxgiDevice;
...
m_d3dDevice.As(&dxgiDevice);

我尝试过这样的事情,但我不确定它是否可以。

ID3D11Device1* m_d3dDevice;
IDXGIDevice1* dxgiDevice;
...
dxgiDevice = reinterpret_cast<IDXGIDevice1*>(m_d3dDevice);

标签: c++directx-11wrl

解决方案


这些是 COM 对象指针。

我不确定您为什么不想使用 COM 智能指针模板类。它们消除了大多数可能使您发疯的引用计数问题。而且它们的开销几乎为零。

因此,您可以使用 ComPtr 类或 ATL 中的旧版 CComPtr 作为您的智能 ptr 模板类型,以自动处理您自己的 Addref、Release 和 QueryInterface 调用。您也可以滚动您自己的智能指针类,但 ComPtr/CComPtr 的编写效率很高。

当您尝试在不使用 QueryInterface 的情况下在接口之间进行转换时,COM 的规则基本上经常被打破。实际的具体实现可能是从多个接口继承的 C++ 类。因此,接口之间的转换可能是指针值的转变。但是编译器不能仅从基类接口推断出这一点。此外,许多 COM 类通过让 QueryInterface 返回一个完全不同的对象来欺骗这一点。

所以,而不是这个:

dxgiDevice = reinterpret_cast<IDXGIDevice1*>(m_d3dDevice);

这可能就是您所需要的:

HRESULT hr = m_d3dDevice->QueryInterface(&dxgiDevice);

一些旧版 SDK 没有 IUnknown::QueryInterface 的模板重载,因此无需处理 IID guid。所以完整的扩展功能实际上是这样的:

HRESULT hr = m_d3dDevice->QueryInterface(__uuidof(IDXGIDevice1), (void**)&dxgiDevice);

或者最“老派”的方式(假设您知道如何链接 IID 变量的定义)。dxguids.lib 可能仍然是一个东西,否则,DEFINE_GUID 的头文件会被破解。

HRESULT hr = m_d3dDevice->QueryInterface(IID_IDXGIDevice1, (void**)&dxgiDevice);

推荐阅读