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