我需要将一些API封装在C中的C++库中。我过去就这样做过,使用了指向类对象的不透明指针、外挂的"C“等等,如这里所描述的。但是,我正在处理的这个新库广泛地使用了引用计数智能指针。我不知道如何在有智能指针的情况下进行包装。例如,假设C++库具有以下功能:
SmartPointer<MyClass> foo() {
SmartPointer<MyClass> ret(new MyClass); // Create smart pointer ret
ret->DoSomething(); // Do something with ret
return ret;
}
如何用C包装foo()
?显然,我需要一个不透明的指针(如void*
或空的struct指针),可以在C函数中使用这个指针来引用MyClass
对象。我想到的第一个选项是从MyClass
中提取ret
对象,并将其转换为一个void*
。但是,由于智能指针所做的自动删除(如果我错了,请纠正我的错误),一旦void*
超出范围,这个ret
就会摇摇欲坠。
另一个选项是将指针分配给智能指针(例如retPtr
),执行*retPtr=ret
,然后创建指向retPtr
的不透明指针。我认为这个选择可能有效,但这是最好的方法吗?
任何帮助都是非常感谢的。
发布于 2016-10-14 01:10:29
注释表明,C代码需要保存智能指针,但除了逐字将其传递给另一个C++函数之外,不需要对它做任何事情。这方面的代码可以是:
// Shared header
#ifdef __cplusplus
extern "C" {
#endif
void * foo_acquire(void);
int foo_bar(void *);
void foo_release(void *);
#ifdef __cplusplus
}
#endif
// C++ implementation
extern "C" void *foo_acquire()
{
return new SmartPointer<MyClass>( foo() );
}
extern "C" int foo_bar(void *s)
{
auto& sp = *static_cast< SmartPointer<MyClass> * >(s);
return bar(sp); // bar represents some function expecting the smart pointer
}
extern "C" void foo_release(void *s)
{
delete static_cast<SmartPointer<MyClass> *>(s);
}
这使用SmartPointer
的移动构造函数(如果没有移动构造函数,则使用复制构造函数),智能指针应该支持该操作。
如果要防止C代码中的隐式转换,可以使用不透明句柄而不是void *
。(例如,以void *
为成员的结构)。
发布于 2016-10-13 21:49:19
您几乎必须返回一个指向C代码的不透明指针。因此,您需要使用new
来分配一个可以返回指针的新智能指针。
您唯一的选择是使用共享指针的集合来保持对象的活动。当C代码指示它与对象一起完成时,您将从集合中移除共享指针。这允许您将任何类型的标识符返回给C代码--它只是用作句柄来查找集合中的对象。
发布于 2016-10-13 22:33:59
除了的答案之外,您还可以考虑一种类似于COM的IUnknown的方法。您可以定义一个包含函数指针的结构(在纯C中模拟一个C++接口),并公开一些方法,比如AddRef和function,以增加和释放ref计数。
调用方获得指向该结构的指针,因此他/她可以使用AddRef和Release来控制返回对象的正确生存期。
此外,还可以在结构中添加其他方法(函数指针),以公开返回对象的其他功能。
本文介绍了C语言中的COM详细地解释了一些事情。
https://stackoverflow.com/questions/40031537
复制相似问题