C++ – boost::shared_ptr to void * and vice versa

boostc

I am developing an application in C, where I need to used a 3rd party C++ library. So, I am basically writing a wrapper around the C++ library to make it possible to call it from my application which is in pure C. Some of the methods in the library returns pointer of type boost::shared_ptr, which I need to cast to void* [for C] and then convert it back to boost::shared_ptr type to reuse it for further processing. I used the following ways to do the conversion:

To void* :

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

From void* :

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

However, I am getting SIGSEGV in func2, which I believe is happening because the shared_ptr being deallocated because its ref-count getting 0.

I was looking for correct ways to do this conversion and suggestions from experts of the SO community.

Thanks in advance!

Best Answer

Think about who owns the instance of T, and when.

I'm guessing you're getting a shared_ptr from your C++ library function, getting its value, then letting the shared_ptr go out of scope. When this happens, as you suggested, the managed object will be deleted.

To get around this, you will have to keep the original shared_ptr alive for the lifetime of your use of its managed object.

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

You could also use a trick with a customer deleter object to effectively release the managed object from the shared_ptr, but this might not be safe if there are other instances of shared_ptr hanging around which manage the same object. See here: Detach a pointer from a shared_ptr?

To pass it back in:

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