c++ - 没有 ->Release() 的 DirectX

标签 c++ memory-management com directx

编写 DIY 内存管理器最令人满意的部分是构建它,这样您就可以忘记 [删除](例如,通过将所有内容捆绑到一个单独分配/取消分配的缓冲区中)。

DirectX 处理对象创建的方式意味着您不能简单地将无效内存转换为您想要创建的类型(可以吗?)并且您必须依赖 COM(+ 记住在每个析构函数中 [Release] 本地内存) 反而。有什么方法可以颠覆这一点并说服 DirectX 使用我的指针吗?

代替:

ID3D12Thing* thng = DirectX::CreateThing();
...
thng->Release();
thng = nullptr;

我要:

ID3D12Thing* thng = DirectX::CreateThingAt(Allocator->AlignedAlloc(sizeof(ID3D12Thing));
...
[memory emptied during shutdown]

最佳答案

编辑:此答案已被 Chuck Walbourn 的平行答案取代。 虽然我的回答并非完全错误,但经过一些调查后,我很确定 Chuck Walbourn 使用 Microsoft::WRL::ComPtr 的建议是更好的选择(另请参阅 C.B. 的回答下的评论部分原因)。 /编辑

据我所知,不可能在 Direct X 结构上植入外部存储器,因为它们都是由 Direct X 本身创建的。

然而,如果主要目标是维护和安全,则可以定义一个 std::unique_ptr 和一个自定义删除器来完成释放工作。

struct DxDeleter {
    void operator() (IUnknown* _moribund) { if(_moribund) _moribund->Release(); }
};
typedef std::unique_ptr<ID3D11Buffer,DxDeleter>                 dx_buffer_ptr; 
typedef std::unique_ptr<ID3D11ShaderResourceView,DxDeleter>     dx_resource_ptr; 
typedef std::unique_ptr<ID3D11UnorderedAccessView,DxDeleter>    dx_access_ptr; 
...

然后指针简单地分配给例如。 myUniqueDxBufferPtr.reset( myRawBufferPtr ) 或类似的。

这有很大的好处,即不需要跟踪版本。这不仅适用于 Direct X,而且适用于需要分配和释放的各种外部库(例如,我对 Freeimage 和 ffmpeg 也使用相同的技术)。

也可以为多个项目共享的资源定义 std::shared_ptr(例如,只要存在任何缓冲区,您就可以让设备保持事件状态)。但这是小心处理 - 与std::unique_ptr 相反,std::shared_ptr 没有删除器作为模板参数,但作为 ctor 参数 - 这使得错误地分配缺少删除器(泄漏)的东西变得非常容易。

void g_dxDelete( IUnknown* _moribund ) {
    if( _moribund )
        _moribund->Release();
}

typedef std::shared_ptr<ID3D11Device> dx_device_shared;
inline dx_device_shared assignDevice( ID3D11Device* _device ) {
    return std::move( dx_device_shared( _device, g_dxDelete ) );
}

在这种情况下,您必须始终确保使用 dx_device_shared myDevice = assignDevice(myRawDevicePtr) 分配创建的设备,但绝不能使用 dx_device_shared myDevice = myRawDevicePtr

关于c++ - 没有 ->Release() 的 DirectX,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49836725/

相关文章:

c++ - _IDTExtensibility2,要将什么 DLL 导入到 ATL 项目中?

c# - 通过 COM 互操作访问 C# 中的 protected 内存

c++ - 如何在 C++ 中将 pid 转换为 const char 指针?

c++ - 从方法内部调用自析构函数

c++ - CMake 没有将共享库的链接依赖项传播到我的可执行文件

c# - 我可以通过在 C# 中通过引用传递 DateTime 参数来减少内存分配吗?

android - 应用程序加载时分配大内存

c++ - Ada 中的 placement new 相当于什么?

c++ - 用c++直接写到屏幕

.net - 在 Delphi 程序中托管 .NET 运行时