删除智能指针

Removing smart pointers

我正在测试 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);

这些是 COM 对象指针。

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

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

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

所以,而不是这个:

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 变量的定义中 link )。 dxguids.lib 可能仍然存在,否则,DEFINE_GUID.

的头文件会被破解
HRESULT hr = m_d3dDevice->QueryInterface(IID_IDXGIDevice1, (void**)&dxgiDevice);