DirectX12中创建CommandQueue与CommandAllocator的代码差异疑问
DirectX 12中ComPtr在Create函数中的传参差异解析
核心差异拆解
首先明确:你看到的第二种写法是冗余且不规范的,正确写法应为IID_PPV_ARGS(mDirectCmdListAlloc.GetAddressof()),而非对GetAddressOf()的结果再取地址。下面解析两种写法的本质:
IID_PPV_ARGS(&mCommandQueue)的逻辑:
当传入&ComPtr<T>时,IID_PPV_ARGS宏会通过IID_PPV_ARGS_Helper自动完成两个关键操作:- 借助
__uuidof(T)获取对应COM接口的IID(比如IID_ID3D12CommandQueue); - 调用ComPtr内部逻辑,获取其管理的COM对象指针的地址(即
T**类型),再转换为void**传给Create函数。
这是微软推荐的简洁写法,完全利用了ComPtr的封装特性。
- 借助
GetAddressOf()的具体含义:
ComPtr的GetAddressOf()方法,直接返回其内部持有的COM对象指针的地址,类型为T**(比如ID3D12CommandAllocator**)。这个方法的作用是绕过ComPtr的自动封装,直接暴露底层指针的地址,仅适用于需要手动控制指针赋值的场景。
冗余写法能运行的原因
你看到的&mDirectCmdListAlloc.GetAddressof()多做了一次取地址操作,得到的是T***类型。由于C++的隐式类型转换,IID_PPV_ARGS宏最终仍能将其转换为void**,但这种写法既不简洁也易引发误解,完全可以简化为直接传入GetAddressOf()的结果。
总结
两种写法的核心目的一致:给Create函数传递用于接收COM对象的void**指针,并提供对应的IID。实际开发中,推荐使用IID_PPV_ARGS(&ComPtr<T>)的简洁写法,GetAddressOf()仅在需要手动操作底层指针时使用。
内容的提问来源于stack exchange,提问作者우현우
相关产品推荐
相关产品推荐

