我正在尝试将指向不同类型着色器的接口(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))
...
附言
除非我遗漏了什么,因为 ID3D11VertexShader
是 ID3D11DeviceChild
的派生类,所以您不需要这里的 static_cast
:
shaders.push_back(static_cast<ID3D11DeviceChild*>(VS));
这应该没问题:
shaders.push_back(VS);
关于CAdapt
的注意事项
请注意,您可能需要将 CAdapt
与 std::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/