boost::shared_ptr 为 void *,反之亦然

Sau*_*loi 6 c c++ boost

我正在用 C 开发一个应用程序,我需要在其中使用 3rd 方 C++ 库。所以,我基本上是在围绕 C++ 库编写一个包装器,以便可以从我的纯 C 应用程序中调用它。库中的某些方法返回 boost::shared_ptr 类型的指针,我需要将其转换为void* [for C] 然后将其转换回 boost::shared_ptr 类型以重用它进行进一步处理。我使用以下方法进行转换:

作废*:

void * func1()
{
    //after the boost::shared_ptr is created
    return static_cast<void *> (SHARED_PTR.get())
}
Run Code Online (Sandbox Code Playgroud)

从 void* :

void func2(void * VOID_PTR) //VOID_PTR returned by func1
{
    boost::shared_ptr<T> SHARED_PTR = *(boost::shared_ptr <T> *)(VOID_PTR);
}
Run Code Online (Sandbox Code Playgroud)

但是,我在 func2 中收到了 SIGSEGV,我相信这是因为 shared_ptr 被释放,因为它的引用计数为 0。

我正在寻找正确的方法来进行这种转换以及来自 SO 社区专家的建议。

提前致谢!

小智 8

想想谁拥有 T 的实例,以及何时拥有。

我猜你是从你的 C++ 库函数中得到一个 shared_ptr,得到它的值,然后让 shared_ptr 超出范围。发生这种情况时,如您所建议的,将删除托管对象。

为了解决这个问题,您必须在使用其托管对象的整个生命周期内保持原始 shared_ptr 处于活动状态。

void* func1(const boost::shared_ptr<T>& sharedPtr)
{
    add_to_some_kind_of_persistent_storage(sharedPtr);
    return static_cast<void*>(sharedPtr.get());
}
Run Code Online (Sandbox Code Playgroud)

您还可以使用客户删除器对象的技巧来有效地从 shared_ptr 中释放托管对象,但是如果有其他 shared_ptr 实例在管理同一对象,则这可能不安全。请参阅此处:从 shared_ptr 分离指针?

将其传回:

boost::shared_ptr<T> func2(void* voidPtr) //VOID_PTR returned by func1
{
    return boost::shared_ptr<T>(voidPtr);
}
Run Code Online (Sandbox Code Playgroud)