如何使用包含在ComPtr中的Direct3D 11指针获取11.1接口?

7

我正在跟随教程学习,并将常规初始化转换为使用ComPtrs,直到这一行:

ID3D11Device*           g_pd3dDevice = nullptr;
ID3D11Device1*          g_pd3dDevice1 = nullptr;
// Obtain the Direct3D 11.1 versions if available
hr = g_pd3dDevice->QueryInterface( __uuidof( ID3D11Device1 ), reinterpret_cast<void**>( &g_pd3dDevice1 ) );

以下是我预期的直接模拟结果:
Microsoft::WRL::ComPtr<ID3D11Device>    device = nullptr;
Microsoft::WRL::ComPtr<ID3D11Device1>   device1 = nullptr;
// Obtain the Direct3D 11.1 versions if available
hr = device->QueryInterface(__uuidof(ID3D11Device1), reinterpret_cast<ID3D11Device1**>(&device1));

有一些编译器和Intellisense警告(对我来说非常神秘)。它不喜欢强制类型转换,也不喜欢我使用QueryInterface()的方式。

我应该怎么做呢?

错误信息:

Error   1   error C2440: 'reinterpret_cast' : cannot convert from 'Microsoft::WRL::Details::ComPtrRef<Microsoft::WRL::ComPtr<ID3D11Device1>>' to 'ID3D11Device1 **'
Error   2   error C2660: 'Microsoft::WRL::Details::RemoveIUnknownBase<T>::QueryInterface' : function does not take 1 arguments

Intellisense警告(可能有帮助?):


18  IntelliSense: function "Microsoft::WRL::Details::RemoveIUnknownBase<T>::QueryInterface [with T=ID3D11Device]" (declared at line 64 of "C:\Program Files (x86)\Windows Kits\8.1\Include\winrt\wrl/client.h") is inaccessible

你应该在问题中包含相关警告的完整文本。 - Captain Obvlious
3
WRL::ComPtr 是一个非常智能的指针,但对于普通的C++编译器来说太过聪明了。你会得到一堆糟糕的错误信息。正确的语法是 hr = device.As(&device1); - Hans Passant
哇...那确实简化了那一行。我会试试的,汉斯。 - chrisp
是的,看起来参数应该被颠倒,但你是正确的,汉斯。如果你愿意,只需发布一个带有我的误解简要说明的答案,我会标记它。(即device1.As(&device)) - chrisp
1
你需要使用ComPtr::GetAddressOf()以获得等效的行为。请注意,不要盲目地使用“&”与WRL ComPtr一起使用,因为与ATL ComPtr和任何其他我见过的智能指针类不同,它具有潜在的邪恶副作用,也会清除您正在持有的项目。当然,95%的时间里你可能想清除其中的任何现有对象,因为指向指针的指针通常是输出参数,但获取COM指针的引用并有条件地修改代码将现在得到nullptr而不是对象。(至于最干净的方式,就像MooseBoys所说) - Dwayne Robinson
1个回答

8

当使用 ComPtr 时,应该使用 ::As 方法代替 QueryInterface。例如,hr = device.As(&device1);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接