在C接口中使用shared_ptr?

时间:2013-06-15 17:36:48

标签: c++ c shared-ptr

我有一个C库,我正在移植到C ++,它大量使用手动引用计数的结构。我已经考虑使用shared_ptr来自动处理引用计数,但我还想维护C API。旧签名看起来像这样:

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

如果我使用shared_ptr,有没有办法在C API中有效地公开此手动引用计数?

3 个答案:

答案 0 :(得分:7)

shared_ptr的问题,正如您已经想到的那样,除了通过构造或销毁实例之外,您无法修改引用计数。所以不,没有办法让它工作,除非保持shared_ptr到每个构造的Object,直到它的引用计数降到零,但这样做需要重做大部分引用计数,所以你收获很少。

或许boost::intrusive_ptr是更好的选择。

答案 1 :(得分:1)

您可以使用std::shared_ptr::getobject_create中检索指针的值。

我不确定您应该维护object_retain还是object_release,因为它已由shared_ptr自动处理。

您希望C代码使用您的库吗?如果是这样,那么@Angew在他的评论中指出,看看Boost.intrusive_ptr,它似乎是最好的选择。

如果你可以假设用C语言编写的客户端代码将使用C库(我认为有意义),那么你可以完全删除这些函数并在内部处理所有函数。如果需要,您可以提供与C api兼容的原始指针,但可以使用shared_ptr自动处理所有生命周期管理。

答案 2 :(得分:0)

由于C中没有RAII,因此您将需要通过create / destroy函数自己管理共享指针。因此,您返回的句柄应为shared_ptr-s,并且您的API如下所示:

// Opaque pointer wrapped in structure for type safety (in header)
typedef struct 
{
    void *ptr;
} ObjectHandle;

// Hide the gory details of resolving the shared ptr.
static std::shared_ptr<Object>* resolveHandle(ObjectHandle objectHandle)
{
    return static_cast<std::shared_ptr<Object>*>(objectHandle.ptr);
}

// Just a sample on how to fully resolve the object for internal use.
static Object* resolveObject(ObjectHandle objectHandle)
{
    return resolveHandle(objectHandle)->get();
}

// Public API functions.

ObjectHandle object_create(void)
{
    return ObjectHandle{new std::shared_ptr<Object>(new Object())};
}

ObjectHandle object_retain(ObjectHandle o)
{
    return ObjectHandle{new std::shared_ptr<Object>(*resolveHandle(o))};
}

void object_release(ObjectHandle o)
{
    delete resolveHandle(o);
}