有没有办法将共享 ptr 转换为 void 指针,然后将 void 指针转换回共享指针?
Posted
技术标签:
【中文标题】有没有办法将共享 ptr 转换为 void 指针,然后将 void 指针转换回共享指针?【英文标题】:Is there a way to cast a shared ptr to void pointer and then cast the void pointer back to shared pointer? 【发布时间】:2021-12-31 18:37:27 【问题描述】:我在整个应用程序中都有一个对象共享指针。这是一个例子:
std::shared_ptr<MyTexture> texture = loadImageFromFile("someFile.png");
我正在使用一个名为 ImGui 的 UI 库,这个库有一个纹理 ID 的概念,它是一个 void 指针。我目前正在通过执行以下操作将数据传递给该库:
ImGui::Image(texture.get());
我的后端将这些纹理存储在指向图形 API 相关数据类型(它是 Vulkan 描述符集但是)的映射中,以便能够渲染纹理。现在,我对此有一个特别的问题。我想用智能指针来管理它。但是,我将它作为原始指针传递;所以,我不能把它包装在一个共享指针中,因为原来的共享指针会被它破坏。在内部,我在任何地方都使用共享指针,除了这个特殊情况。有什么方法可以将共享指针对象本身作为原始 void 指针传递,然后将其转换回共享指针;那么,将指针传递给此函数时,我不会丢失共享指针计数器吗?
【问题讨论】:
如果Image
接受void*
,那么它必须假定它不对所有权负责。如果无法访问原始文件,则无法将 void*
有意义地重新包装在 shared_ptr
中。
std::shared_ptr::get()
不会减少使用次数,所以我不明白你的担心——“因为原来的共享指针会被这个破坏。”
@Gasim 好吧,这听起来像是共享所有权的情况,只是要小心所有权的方向,然后避免这些循环。
如果其他所有内容都删除了对MyTexture
的引用,而唯一的引用是Image
,会发生什么?如果这种情况是不可能的,那么您可以通过std::enable_shared_from_this
采取简单的方法。
@Gasim:“当这些对象没有明确的所有者时,跟踪它们的生命周期真的很复杂。”你的问题是过度所有权。您不应该希望材质的破坏导致纹理的破坏。应该有一些更高级别的系统来了解您的应用程序如何使用 GPU 资源和引擎资源。只有在更高级别的系统需要时才应该删除纹理。该系统有责任确保如果存在任何仍在使用它的活性材料,它不会想要这样做。
【参考方案1】:
不,不是std::shared_ptr
,我的意思是,您可以从智能指针中获取原始指针,但您根本无法获取 SAME-REF-COUNTER(包装在智能指针中) 来自原始指针。
但你可以:
只需确保您的“void *
”使用永远不会超过智能指针(否则期望未定义的行为)。
或者实现自己的智能指针类,它具有内部哈希映射,将实例存储为值(以原始指针作为键),然后在方法中通过“void *
”找到并返回智能指针" 输入(例如:static MySmartPtr fromRaw(void *)
)。
或手动将std::shared_ptr
存储在哈希映射中(如上,但没有自定义智能指针实现)。
【讨论】:
以上是关于有没有办法将共享 ptr 转换为 void 指针,然后将 void 指针转换回共享指针?的主要内容,如果未能解决你的问题,请参考以下文章