How do I use a Direct3D 11 pointer wrapped in ComPtr to get a 11.1 interface?
Asked Answered
P

1

7

I'm following tutorials and I've converted the usual initialisation to using ComPtrs up to this line:

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 ) );

Here's what I expected to be the straight analog:

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));

There's a number of compiler and Intellisense warnings (really cryptic to me). It doesn't like the cast, and it doesn't like how I'm using QueryInterface().

What should I be doing?

Errors:

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 Warnings (could be helpful?):

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
Procopius answered 16/1, 2014 at 20:14 Comment(5)
You should include the full text of the relevant warnings in your question.Divorcement
WRL::ComPtr is a very smart pointer, unfortunately too smart for the average C++ compiler. The litany of error messages you get is quite lousy. Proper syntax is hr = device.As(&device1);Saturable
Wow... that sure simplifies that line. I'll give it a shot Hans.Procopius
Yeah looks like the parameters should be reversed, but you were correct Hans. If you'd like, just post an answer with a brief detail my of misconception and I'll mark it. (i.e. device1.As(&device))Procopius
You'd need to use ComPtr::GetAddressOf() for equivalent behavior. Beware of using "&" blindy with WRL ComPtr because unlike ATL ComPtr and any other smart ptr class I've seen, it has the potentially evil side-effect of also clearing the item you are holding onto. Granted, 95% of the time you probably would want to clear any existing object that might be in it, because pointers to pointers are generally out parameters, but code that takes a reference to a COM pointer and conditionally modifies will now get nullptr instead of the object. (As for the cleanest way though, As, like MooseBoys said)Searcy
C
8

When using ComPtr, you should use the ::As method instead of QueryInterface. For example, hr = device.As(&device1);

Canard answered 16/1, 2014 at 22:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.