c++ - 转换 DirectX 接口(interface)

标签 c++ com directx

我正在尝试将指向不同类型着色器的接口(interface)指针放在像这样的 vector 中:

std::vector<ID3D11DeviceChild*> shaders;
ID3D11VertexShader* VS;
// ... instantiate and init VS
shaders.push_back(static_cast<ID3D11DeviceChild*>(VS));
// and when VS is needed again:
ID3D11VertexShader* VS = static_cast<ID3D11VertexShader*>(shaders[i]);
// use VS here

我的问题是这种类型转换 COM 接口(interface)的方法是否安全。我知道它适用于普通的多态类层次结构,但我不确定 COM。

最佳答案

首先,我建议在像 std::vector 这样的 STL 容器中存储智能指针而不是原始拥有指针,例如

std::vector<CComPtr<ID3D11DeviceChild>> shaders;

在 STL 容器内使用原始拥有指针是泄漏、潜在错误和异常不安全代码的来源(不过,观察原始指针没问题)。

要从 ID3D11DeviceChild* 向下转换为 ID3D11VertexShader*,请考虑使用 QueryInterface()(再次使用 ATL 智能指针,如 CComPtr 简化了代码):

CComPtr<ID3D11VertexShader> spVertexShader;
HRESULT hr = (shaders[i])->QueryInterface(IID_PPV_ARGS(&spVertexShader));
if (FAILED(hr))
    ...

附言

除非我遗漏了什么,因为 ID3D11VertexShaderID3D11DeviceChild 的派生类,所以您不需要这里的 static_cast:

shaders.push_back(static_cast<ID3D11DeviceChild*>(VS));

这应该没问题:

shaders.push_back(VS);

关于CAdapt的注意事项

请注意,您可能需要将 CAdaptstd::vector 一起使用:

std::vector<CAdapt<CComPtr<ID3D11DeviceChild>>> shaders;

一致的 C++11 STL 实现应该需要 CAdapt,但我认为至少对于 VS2008 和 VS2010 是必要的。
我不确定 Visual Studio 的更现代版本,但似乎他们修复了这个问题,例如:
您可能想阅读 this Visual C++ blog post 中标题为 “对重载地址运算符的抵抗” 的段落.

关于c++ - 转换 DirectX 接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24754886/

相关文章:

c++ - 在 C++ 或 Qt 中格式化 XML 文件

c++ - 现代 OpenGL 3.3 核心黑色纹理

c# - 为 System.Net.NetworkInformation.Ping 创建 COM 可调用包装器

.net - 这是为 COM 注册 .NET 类型的一种可能方法吗

c# - 如何在 SharpDX 上获取 Direct2D 位图的像素颜色

c++ - Visual C++ 构建/调试问题

c++ - V8 内存泄漏和条件跳转

c++ - 如何消除 RICHEDIT 控件的 MessageBeep?

c++ - 使用 Direct2D 和 DirectWrite(C++、DirectX)制作按钮

带有 D3DX9 的 C++ - 内存大小以 10 MB/秒的速度不断增加 - 为什么?