将boost::shared_ptr转换为void *,反之亦然

7
我正在开发一款C语言应用程序,需要使用第三方的C++库。因此,我基本上在编写一个包装器,使得我的纯C应用程序能够调用它。库中的一些方法返回boost::shared_ptr类型的指针,我需要将其转换为void* [用于C语言],然后再将其转换回boost::shared_ptr类型,以便进行进一步处理。我使用以下方式来完成转换:
转换为void* :
void * func1()
{
    //after the boost::shared_ptr is created
    return static_cast<void *> (SHARED_PTR.get())
}

从 void* :

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

然而,在func2中我遇到了SIGSEGV错误,我认为这是因为shared_ptr被销毁,因为它的引用计数变为0。

我正在寻找正确的转换方式,并期待SO社区专家的建议。

提前感谢!


1
难道后向转换不应该是初始化吗?比如 boost::shared_ptr<T>(VOID_PTR) - user529758
不行。那样你就会有两个智能指针都有删除该指针的责任。 - Cheers and hth. - Alf
@Cheersandhth.-Alf:“_那你就会有两个智能指针了_” 我想你什么也得不到:如果你不能做 delete p;,你怎么能做 boost::shared_ptr<T>(p) 呢? - curiousguy
3个回答

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());
}

你还可以使用一个客户端删除器对象的技巧,有效地释放shared_ptr中管理的对象,但是如果还有其他实例的shared_ptr管理相同的对象,则这可能不安全。 请见:Detach a pointer from a shared_ptr? 将其传回:
boost::shared_ptr<T> func2(void* voidPtr) //VOID_PTR returned by func1
{
    return boost::shared_ptr<T>(voidPtr);
}

2

现在shared_ptr已经成为标准库的一部分

std::shared_ptr<type> ptr;
auto ptr1 = reinterpret_cast<void *>(&ptr); /* shared_ptr > void ptr */
auto ptr2 = * reinterpret_cast(std::shared_ptr<type>*)(ptr1); /* void ptr > shared_ptr */

你为什么要在这里使用reinterpret_cast - curiousguy
auto ptr2 = reinterpret_cast<std::shared_ptr<type>>(ptr1); - Rodrigo Borba

1

根据C库对void*指针的处理方式来决定下一步该怎么做。如果在某个时刻将其用作T*,那么你需要像目前这样传递它。为了获得一个shared_ptr,你需要让T实现boost::enable_shared_from_this,并调用其shared_from_this成员函数,即reinterpret_cast<T*>(void_ptr)->shared_from_this()


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接