1 structurepython
我看来,structure乃是封装之源。SWIG对于strucure的封装很是天然。天然的意思就是,C语言里怎么用PYTHON就怎么用。水里水里来,火里火里去。不过第一个问题就是,PYTHON做为面向对象的语言, 它自己就是没有struct的。不过不要紧,咱们还有class。c++
使用的方法很是简单。直接把struct的定义写到SWIG脚本文件里面去就行了。数组
struct Vector { double x,y,z; };
使用起来也很是的方便。ide
>>> v = example.Vector() >>> v.x = 3.5 >>> v.y = 7.2 >>> print v.x, v.y, v.z 7.8 -4.5 0.0 >>>
若是你打印出v的值,你会发现这个实例只是对底层Vector结构体指针的封装。这个实例自己什么也不作,它只是一个代理类。能够用.this的方式访问Vector结构体的指针。函数
>>> print v <C Vector instance at _18e31408_p_Vector> >>> print v.this _18e31408_p_Vector >>>
像全局变量同样,你能够在结构体定义内部用%immutable和%mutable指令来告诉SWIG哪些字段不可被修改,那些能够被修改。这两条指令的做用范围是在结构体以内的。this
struct Foo { ... %immutable; int x; /* Read-only members */ char *name; %mutable; ... };
若是你在struct中拥有char* 这种类型的字段,SWIG会用malloc或者new来分配内存呢。具体用哪种要看你在运行swig时候是否使用了-c++这个参数。假如在python中对char*字段从新赋值,会先释放掉内存再申请一块新的内存。若是你以为这种行为不符合你的要求,你能够用typemap来自定义行为。不过之后才会介绍typemap这个特性。翻译
若是有数组类型的字段,那么在python中同样是看成指针来处理的。好比有这样的结构体代理
struct Bar { int x[16]; };
python中运行结果以下:指针
>>> b = example.Bar() >>> print b.x _801861a4_p_int >>>
像全局变量同样,你也能够用另一个数组给这个数组来赋值,其实是执行的值拷贝操做。code
>>> c = example.Bar() >>> c.x = b.x # Copy contents of b.x to c.x
对数组赋值时, python实际上拷贝了b.x的16个int型整数到c.x所指向的位置。不过要注意一点,PYTHON不会为你作边界检查,若是你传了一个错误的地址是颇有可能致使段错的。
结构体自己能够做为其余结构体的字段。但在swig中,这种结构体类型的字段是做为指针来处理的。假若有结构体Foo和Bar:
struct Foo { int a; }; struct Bar { Foo f; };
PYTHON中在Bar中能够像访问一个普通的属性同样访问Foo结构体。一切都很是天然。
>>> b = Bar() >>> x = b.f
在这个例子中,x其实只是一个指向Foo的指针。结构体类型的字段和结构体指针类型的字段在SWIG中的处理方式是同样的。将上面的代码翻译成C语言的代码,就像这样
Bar b; Foo *x = &b->f; /* Points inside b */
2 class
c++的class固然也会装到PYTHON的class的类中。好比下面这个类:
class List { public: List(); ~List(); int search(char *item); void insert(char *item); void remove(char *item); char *get(int n); int length; };
在PYTHON里面这样方便的使用它:
>>> l = example.List() >>> l.insert("Ale") >>> l.insert("Stout") >>> l.insert("Lager") >>> l.get(1) 'Stout' >>> print l.length 3 >>>
类的数据成员的访问方式和struct中基本同样。除了静态成员。
静态成员和PYTHON的访问方式有些不大相同。SWIG提供两种访问类的类成员函数的方法。第一种是直接经过对象来访问,第二种是能够经过‘类名_函数名’ 做为global函数的使用的方式。
>>> example.Spam_foo() # Spam::foo() >>> s = example.Spam() >>> s.foo() # Spam::foo() via an instance
类数据成员如何访问,还记得全局变量是怎么访问的吗? SWIG将全局变量放在一个cvar的模块对象中。类数据成员的访问方法也是相似的,也是做为模块的全局变量来访问。
>>> print example.cvar.Spam_bar 7
3 继承
SWIG彻底支持C++的继承方式。假若有这样的类的继承关系
class Foo { ... }; class Bar : public Foo { ... };
你就能够惊奇的发如今python里也能够拥有相同的继承关系:
>>> b = Bar() >>> instance(b,Foo) 1 >>> issubclass(Bar,Foo) 1 >>> issubclass(Foo,Bar) 0
你能够在此处下载本文中的例子, https://dl.dropbox.com/u/35106490/swig4.tgz