简体   繁体   English

WRL::ComPtr 导致 d3d 中的 object 泄漏?

[英]WRL::ComPtr causes object leaks in d3d?

I am making a simple d3d 11 application and I'm using the Microsoft::WRL::ComPtr to release the resources automatically.我正在制作一个简单的 d3d 11 应用程序,并且正在使用 Microsoft::WRL::ComPtr 自动释放资源。 For some reason though when the applications exits I'm getting 30-40 Live Object warnings from d3d.出于某种原因,尽管当应用程序退出时,我从 d3d 收到 30-40 条 Live Object 警告。 I could have missed one or two, but this seems more like the count of all objects I have.我可能会错过一两个,但这似乎更像是我拥有的所有对象的计数。 I'm obviously doing something wrong.我显然做错了什么。 My general usage would be to have a member in some wrapper class:我的一般用法是在一些包装器 class 中有一个成员:

class graphics_device
{
   // ...
   ComPtr<ID3D11Device> hwdevice;
}

Which in theory should release the object upon class destruction.理论上应该在 class 破坏时释放 object。 (I'm creating most objects on stack and I've double checked that I delete the ones that are on the heap) (我在堆栈上创建了大多数对象,并且我仔细检查了我是否删除了堆上的对象)

When I create my functionality I pass them around as references.当我创建我的功能时,我将它们作为参考传递。 For example:例如:

void graphics_device::create_constant_buffer(u32 size, const void* data, ComPtr<ID3D11Buffer>& constantBuffer)
{
    D3D11_BUFFER_DESC bufferDesc;
    ZeroMemory(&bufferDesc, sizeof(bufferDesc));

    bufferDesc.Usage = D3D11_USAGE_DEFAULT;
    bufferDesc.ByteWidth = size;
    bufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    bufferDesc.CPUAccessFlags = 0;

    D3D11_SUBRESOURCE_DATA initData;
    ZeroMemory(&initData, sizeof(initData));
    initData.pSysMem = data;

    device->CreateBuffer(&bufferDesc, &initData, &constantBuffer);
}

Any ideas what I'm missing?有什么我想念的想法吗?

EDIT: Forgot to post the warnings from d3d11:编辑:忘记发布来自 d3d11 的警告:

D3D11 WARNING:  Live Object at 0x0061D93C, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING:  Live Object at 0x0061DBE4, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING:  Live Object at 0x0061DE8C, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: Live                         Object :     31 [ STATE_CREATION WARNING #0: UNKNOWN]
DXGI WARNING: Live Producer at 0x005ADDC0, Refcount: 4. [ STATE_CREATION WARNING #0: ]
DXGI WARNING:   Live Object at 0x005B7FD0, Refcount: 2. [ STATE_CREATION WARNING #0: ]
DXGI WARNING: Live                         Object :      1 [ STATE_CREATION WARNING #0: ]

And many more similar.还有更多类似的。 I'm not getting any other warnings during runtime.在运行时我没有收到任何其他警告。

Getting a 'clean exit' can be a little challenging.获得一个“干净的出口”可能有点挑战。 It's not likely to be ComPtr if used correctly.如果使用正确,它不太可能是ComPtr Per the comment, a good place to start is object naming .根据评论,一个好的起点是object 命名 Remember that the output happens when the Direct3D Device is released, so you may need to look at the 'release order' to get it to cleanly exit.请记住 output 发生在 Direct3D 设备发布时,因此您可能需要查看“发布顺序”以使其干净退出。 There are also 'internal' vs. 'external' ref-counts so they can be a little confusing.还有“内部”与“外部”参考计数,因此它们可能会有些混乱。 See this blog post for some notes on the debug layer usage.有关调试层使用的一些说明,请参阅此博客文章

Another thing to keep in mind is that Direct3D object reporting can't really tell you about DXGI-owned objects.要记住的另一件事是 Direct3D object 报告不能真正告诉您有关 DXGI 拥有的对象的信息。 That's why also using DXGI Debug Device can be useful as well.这就是为什么使用DXGI 调试设备也很有用的原因。

The directx-vs-templates put all advice from these blog posts in one place, so you might want to look at them. directx-vs-templates将这些博客文章中的所有建议放在一个地方,因此您可能需要查看它们。

Finally, passing ComPtr as a parameter is generally not the best use case even by reference.最后,将ComPtr作为参数传递通常不是最好的用例,即使是通过引用也是如此。 Using ComPtr as data members and local variables is great, but usually as parameters it's best to use "raw pointers" since the lifetime is implicit already.使用ComPtr作为数据成员和局部变量很好,但通常作为参数最好使用“原始指针”,因为生命周期已经是隐式的。 So your function signature would be better as:所以你的 function 签名会更好:

void graphics_device::create_constant_buffer(u32 size, const void* data, ID3D11Buffer** constantBuffer);

Then when calling that function, you use a ComPtr :然后在调用 function 时,您使用ComPtr

ComPtr<ID3D11Buffer> cb;
graphicsdevice->create_constant_buffer(size, data, &cb);

See this wiki on ComPtr for some hints on using it most effectively.有关最有效地使用它的一些提示,请参阅ComPtr 上的这个 wiki

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM