Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using shared_ptr in C interfaces?

Tags:

c++

c

shared-ptr

I have a C library that I'm porting to C++ that makes heavy use of manually reference-counted structs. I've considered using shared_ptr to automatically handle the reference counting, but I also want to maintain the C API. The old signatures look something like this:

Object* object_create(void);
Object* object_retain(Object* o);
void object_release(Object* o);

If I use shared_ptr, is there any way to effectively expose this manual reference counting in a C API?

like image 566
Alexis King Avatar asked Jun 15 '13 17:06

Alexis King


People also ask

Why would you choose shared_ptr instead of Unique_ptr?

Use unique_ptr when you want to have single ownership(Exclusive) of the resource. Only one unique_ptr can point to one resource. Since there can be one unique_ptr for single resource its not possible to copy one unique_ptr to another. A shared_ptr is a container for raw pointers.

What is the use of shared_ptr?

shared_ptr is also helpful in C++ Standard Library containers when you're using algorithms that copy elements. You can wrap elements in a shared_ptr , and then copy it into other containers with the understanding that the underlying memory is valid as long as you need it, and no longer.

Is shared_ptr thread safe?

std::shared_ptr is not thread safe. A shared pointer is a pair of two pointers, one to the object and one to a control block (holding the ref counter, links to weak pointers ...).

How slow is shared_ptr?

Admittedly, the std::shared_ptr is about two times slower than new and delete. Even std::make_shared has a performance overhead of about 10%.


2 Answers

The problem with shared_ptr, as you'll have figured out already, is that you can't modify the reference count except by constructing or destroying instances. So no, there's no way to get this to work except by keeping a shared_ptr to every constructed Object around until its reference count drops to zero, but doing that right entails redoing much of the reference counting, so you gain very little.

Perhaps boost::intrusive_ptr is a better option.

like image 61
Fred Foo Avatar answered Sep 20 '22 08:09

Fred Foo


You can use std::shared_ptr::get to retrieve the value of your pointer in your object_create.

I'm not sure that you should maintain object_retain or object_release as it is already automatically handled by the shared_ptr.

Do you want your library to be used by C code? If so then as @Angew pointed out in his comment, have a look at Boost.intrusive_ptr, it seems to be the best choice.

If you can assume that client code written in C will use the C library (which I think kind of make sense), then you can completely drop these functions and handle all internally. You can provide a raw pointer for compatibility with C api if you need to but all the lifetime management could be handled automatically with shared_ptr.

like image 36
Uflex Avatar answered Sep 18 '22 08:09

Uflex