这对于手动完成来说并不太难,但取决于界面的大小。
我所做的例子是在纯 C 代码中使用我们的 C++ 库,因此 SWIG 没有太大帮助。 (好吧,也许 SWIG 可以用来做到这一点,但我不是 SWIG 专家,这看起来并不简单)
我们最终所做的就是:
- 在 C 中,每个对象都会传递一个不透明的句柄。
- 构造函数和析构函数被封装在纯函数中
- 成员函数是纯函数。
- 其他内置函数尽可能映射到 C 等效项。
所以像这样的类(C++ 头文件)
class MyClass
{
public:
explicit MyClass( std::string & s );
~MyClass();
int doSomething( int j );
}
将映射到这样的 C 接口(C 标头):
struct HMyClass; // An opaque type that we'll use as a handle
typedef struct HMyClass HMyClass;
HMyClass * myStruct_create( const char * s );
void myStruct_destroy( HMyClass * v );
int myStruct_doSomething( HMyClass * v, int i );
接口的实现如下所示(C++ 源代码)
#include "MyClass.h"
extern "C"
{
HMyClass * myStruct_create( const char * s )
{
return reinterpret_cast<HMyClass*>( new MyClass( s ) );
}
void myStruct_destroy( HMyClass * v )
{
delete reinterpret_cast<MyClass*>(v);
}
int myStruct_doSomething( HMyClass * v, int i )
{
return reinterpret_cast<MyClass*>(v)->doSomething(i);
}
}
We derive our opaque handle from the original class to avoid needing any casting, and (This didn't seem to work with my current compiler). We have to make the handle a struct as C doesn't support classes.
这样我们就得到了基本的 C 接口。如果您想要一个更完整的示例来展示一种集成异常处理的方法,那么您可以在 github 上尝试我的代码:https://gist.github.com/mikeando/5394166 https://gist.github.com/mikeando/5394166
现在有趣的部分是确保您将所有必需的 C++ 库正确链接到更大的库中。对于 gcc(或 clang),这意味着仅使用 g++ 执行最后的链接阶段。