我正在考虑用 c++ 包装一些 c 库,但我不确定包装不透明指针的最佳方法是什么。
当 C 结构是公共 API 的一部分时
typedef struct _SomeType
{
int a;
int b;
} SomeType_t;
有几个“成员”功能的地方:
void SomeTypeFoo( SomeType_t* obj, ... );
void SomeTypeBar( SomeType_t* obj, ... );
我喜欢从基础派生的方法,将这些“成员”函数简单地关联为实际的类成员。IE:
class SomeTypeWrapper:
public SomeType_t
{
void foo( ... );
void bar( ... );
};
就我的理解而言,我相信这SomeTypeWrapper
是“二进制兼容的” struct _SomeType
,SomeTypeWrapper*
可以强制转换为,SomeType_t*
以便 c++ 方法实现可能是:
SomeTypeWrapper::foo( ... )
{
SomeTypeFoo( (SomeType_t*)this, ... );
}
见注[1]。
但是,在某些库中,他们喜欢将结构的定义保持为私有(我想这是为了允许在不更改 headers/API 的情况下更改实现)。所以在标题中我有这样的东西:
typedef struct _SomeType SomeType_t;
然后所有的“成员”函数都处理这些不透明的指针。为了将这些方法“包装”到一个接口中,到目前为止我所做的是提供一个包含指针的类。
class SomeTypeWrapper
{
private:
SomeType_t* m_data;
public:
SomeTypeWrapper( SomeType_t* data ): m_data(data){}
void foo(...);
void bar(...);
};
这意味着对于 c 库中返回这种不透明指针的任何函数,我必须分配一个新对象来携带该指针。对于许多可能很好但这种设计使包装器实现复杂化的库以及执行大量小对象分配的快速 c 库,我怀疑这种额外的对象开销会导致显着的性能损失。此外,底层对象可能是引用计数的,所以在某些情况下,我必须决定 SomeWrapperType 是否增加引用计数、实现复制构造函数、是否具有私有构造函数等。
在大多数情况下,我很乐意为更好的界面付出代价,但我正在寻找其他选择。有没有更简洁的方法来处理 c++ 包装库中的不透明 c 指针?相关:是否有一种实现包装器类的好方法,以便 c++ 标头不必包含 c-library 标头并且不需要包装器对象分配?
注意[1]:我相信这个转换是安全的,只要使用相同的编译器并且SomeTypeWrapper
不添加额外的成员并且没有虚拟方法。通过相同的编译器,我假设由 gcc 编译的 c 库将与由相同 gcc 编译的 c++ 包装器一起使用。也许这不能保证?