无法释放Direct3D设备“或”相应的上下文

时间:2013-03-17 13:46:26

标签: c++ com directx direct3d

是的,它实际上是“或”。我会解释一下。我正在为自己开发帮助类,比如DirectXToolKit。为了管理COM我使用 Microsoft :: WRL :: ComPtr< T > (wrl.h)

struct Renderer
{
    ComPtr<ID3D11Device> m_Device;
    ComPtr<ID3D11DeviceContext> m_ImmContext;
}

当所有资源都被销毁时,上面结构的实例也应该被销毁,但是在调用dtor之后,我在 Microsoft :: WRL :: ComPtr&lt; T中触发错误&gt; ,当它尝试释放设备或上下文时。

我已经实现了手动释放m_Device和m_ImmContext的dtor,但遗憾的是我尝试发布的最后一个成员总是在函数中遇到问题

unsigned long InternalRelease() throw()
{
    unsigned long ref = 0;
    T* temp = ptr_;

    if (temp != nullptr)
    {
        ptr_ = nullptr;
        ref = temp->Release();
    }

    return ref;
}

这里

ref = temp->Release();

当我首先成功释放设备时,上下文会触发错误,反之亦然(!是的,当其中一个成功释放时,第二个成员的取消失败)。已经存在类似我的问题(destroy directx device and swap chain),但窗口和交换链已经被破坏,就像其他dx资源一样。不知道为什么会发生这种情况。有什么想法吗?

对不起我不完美的英语:3

2 个答案:

答案 0 :(得分:3)

我已经解决了这个问题。问题是我还没有理解 std :: shared_ptr 足够好(函数 std :: make_shared 实际上(about shared pointers and their allocation)):

我创建了像:

这样的指针
Obj *ObjPtr = new Obj();

然后只是:

SomeOtherState.SharedObj = std::make_shared<Obj>(*ObjPtr);

之后并没有破坏 ObjPtr 。在 SomeOtherState 被销毁之后,指向的数据 ObjPtr 仍然在内存中(并且据我所知,如果我使用了std,那么该问题应该也会消失:: shared_ptr ctor)。

很可能是因为这个内存泄漏,但还有一件事我已经改变了: CoUninitialize 调用是在最后一个COM指针被销毁之前进行的,但是来自MSDN: CoUninitialize来了重要的(实际上从第一段开始):

  

关闭当前线程上的COM库,卸载线程加载的所有DLL,释放线程维护的所有其他资源,并强制关闭线程上的所有RPC连接。

所以我已经相应地替换了 CoInitialize CoUninitialize ,问题已经消失。如果有人有同样的麻烦,这可能有点解决(我做过的第一次和第二次改变中的一种或两种)。

我应该为我的问题添加“com”标签

答案 1 :(得分:0)

当您获得ImmediateContext时,问题可能在某处。 根据文件:    http://msdn.microsoft.com/en-us/library/windows/desktop/ff476529%28v=vs.85%29.aspx

The GetImmediateContext method increments the reference count of the immediate
context by one. Therefore, you must call Release on the returned interface pointer
when you are done with it to avoid a memory leak. 

所以我&gt;&gt;&gt;猜测&lt;&lt;&lt;您忘记在某处释放上下文,以便之后设备发布失败。

BTW:确保资源始终以相反的顺序发布。