4

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

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

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

我已经实现了手动释放 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();

当我首先成功释放设备时,上下文会触发错误,反之亦然(!是的,当其中一个成功释放时,第二个成员的销毁失败)。已经有像我这样的问题(销毁 directx 设备和交换链),但是窗口和交换链已经被销毁,就像其他 dx 资源一样。不知道为什么会这样。有任何想法吗?

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

4

2 回答 2

3

我已经解决了这个问题。问题是我对std::shared_ptr的理解不够好(实际上是函数std::make_shared (关于共享指针及其分配)):

我创建了如下指针:

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 连接。

所以我已经相应地替换了CoInitializeCoUninitialize并且问题已经消失了。如果有人遇到同样的麻烦,这可能是一个解决方案(我所做的第一个和第二个更改中的一个或两个)。

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

于 2013-03-17T20:03:28.827 回答
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. 

所以我>>>猜<<<您忘记在某处释放上下文,因此设备发布随后失败。

顺便说一句:还要确保资源总是以相反的顺序释放。

于 2013-03-17T14:20:14.683 回答