主要总结下swig封装类的方法。

为了能够将C++的类映射到目标语言,swig使用目标语言自动生成一个代理类(Proxy Class)来讲真正的C++类封装在里面,并通过使用一些accessor函数来使其看起来和用C++类一样的效果。

举个例子:
我有如下C++的类:

1
2
3
4
5
6
7
8
class Foo
{
public:
Foo();
~Foo();
int bar(int x);
int x;
};

代理类只是一种思想,可以用C++本身来实现一个代理类封装自己的类:

1
2
3
4
5
6
7
8
9
10
11
class FooProxy
{
private:
Foo * this; // 这个指针就是指向真正的被封装的类对象
public:
FooProxy() { this = new_Foo(); } // new_Foo()函数就是一个accessor函数,使用C++创建一个Foo对象,并返回其地址
~FooProxy() { delete_Foo(this); }
int bar(int x) { return Foo_bar(this, x); }
int x_get() { return Foo_x_get(this); }
int x_set(int x) { Foo_x_set(this, x); }
};

当然要生成目标语言的代理类,那就要使用目标函数来生成,使用python的话:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Foo:
def __init__(self):
self.this = new_Foo() # 这里的new_Foo函数是封装过的accessor函数

def __del__(self):
delete_Foo(self.this)

def bar(self, x):
return Foo_bar(self.this, x)

def __getattr__(self, name):
if name == 'x':
return Foo_x_get(self.this)
...

def __setattr__(self, name, value):
if name == 'x':
Foo_x_set(self.this, value)
...

Again, it’s important to emphasize that the low-level accessor functions are always used by the proxy classes.

感觉swig映射或者说封装C/C++的类或者结构的时候是先生成一套accessor functions进行封装,然后生成目标语言的proxy class调用accessor functions形成一个看似和原始类型为相同的封装类。

在这里举个简单的例子:
swig接口文件(temp.i)

1
2
3
4
5
6
7
8
9
10
11
12
%module temp

%inline %{
class A
{
public:
int a_;
A() {}
~A() {}
const a() { return a_; }
};
%}

直接将其编译成模块,在python中执行:

可见封装后的a对象中的this成员是一个指针(在python中是个swigpyobject指针对象),其他的方法也都有相应的accessor function来操作对象。

Comments

2016-04-05