ComPtr.As() 的作用是什么?

Dyl*_*lan 6 c++ com

我正在努力从一些示例中学习 DirectX 12,但我无法理解 ComPtr.As() 方法的作用。

ComPtr<ID3D12Device> device;
ComPtr<ID3D12Device> device2; 

// Do Stuff with Device
device.As(&device2); // What does this do?
Run Code Online (Sandbox Code Playgroud)

Chu*_*urn 4

你在哪里找到这个示例代码?看起来有鱼腥味。这是一种无意义的使用As。如果将其扩展到底层,这同样愚蠢QueryInterface

hr = device->QueryInterface( IID_PPV_ARGS(device2) );
Run Code Online (Sandbox Code Playgroud)

事实上,你的代码最好写成:

device2 = device;
Run Code Online (Sandbox Code Playgroud)

通常,您会用来As从现有接口获取新接口。例如,使用 Direct3D 11,您将设备创建为 Direct3D 11.0 接口,然后必须使用QueryInterface11.1、11.2、11.3 和/或 11.4 版本才能使用它们:

ComPtr<ID3D11Device> device;
DX::ThrowIfFailed(D3D11CreateDevice(..., device.ReleaseAndGetAddressOf());

ComPtr<ID3D11Device2> device2;
hr = device.As(&device2);
if (FAILED(hr))
    // Do whatever handling you do if the system doesn't support 11.2
Run Code Online (Sandbox Code Playgroud)

Direct3D 11 的另一个常见用途是处理可能不存在的调试接口:

#ifndef NDEBUG
    ComPtr<ID3D11Debug> d3dDebug;
    if (SUCCEEDED(device.As(&d3dDebug)))
    {
        ComPtr<ID3D11InfoQueue> d3dInfoQueue;
        if (SUCCEEDED(d3dDebug.As(&d3dInfoQueue)))
        {
#ifdef _DEBUG
            d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true);
            d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true);
#endif
            D3D11_MESSAGE_ID hide [] =
            {
                D3D11_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS,
                // TODO: Add more message IDs here as needed.
            };
            D3D11_INFO_QUEUE_FILTER filter = {};
            filter.DenyList.NumIDs = _countof(hide);
            filter.DenyList.pIDList = hide;
            d3dInfoQueue->AddStorageFilterEntries(&filter);
        }
    }
#endif
Run Code Online (Sandbox Code Playgroud)

同样重要的是不要忽略从As. 您应该使用SUCCEEDEDor宏,或者像ThrowIfFailedFAILED这样的快速失败。

请参阅ComPtr

  • 我来这里用谷歌搜索同样的问题...该代码来自 MSDN 的“所以你想学习 DirectX”代码示例 (3认同)