有没有办法将共享 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 指针转换回共享指针?的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法避免隐式转换为 void*?

使用指针在 C++ 中显示 char 变量的地址?

将ptr转换为派生类的ptr [重复]

如何获取 void* 指针的 typeid?

如何定义指向函数的指针?

将cpp函数指针转换为java接口方法