SWIG入門6: Python Proxy Class和Builtin Type

在前幾篇文章中,從一個較高的層次上說明了SWIG的基本用法。這篇文章會深刻到SWIG的一些實現的細節中。SWIG默認的封裝方式,是把C/C++的struct和class封裝到Python Proxy Class中。不過從SWIG 2.0.4開始, swig提供了一個新的參數-builtin, 這種封裝的方式比Python Proxy Class更高效。python

Python Proxy Class

Python Proxy Class是SWIG封裝的一個很關鍵的部分。Python Proxy Class提供了一個很天然的訪問C/C++代碼的方式,從而能提供不少SWIG的特性。假如你有這樣一段C++的代碼:app

class Foo {
public:
     int x;
     int spam(int);
     ...

SWIG會把這個類的成員變量和成員函數,封裝成一些簡單的函數。例如在foo_wrap.cxx中會有一個_wrap_new_Foo這個函數是對於new Foo的封裝。在這個函數中,先會動態分配一個Foo對象,而後將這個對象包裹在SwigPyObject對象內,最後將這個SwigPyObject的對象返回。函數

/*
Foo *new_Foo() {
    return new Foo();
}
*/

SWIGINTERN PyObject *_wrap_new_Foo(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
  PyObject *resultobj = 0; 
  Foo *result = 0 ;
  
  if (!PyArg_ParseTuple(args,(char *)":new_Foo")) SWIG_fail;
  result = (Foo *)new Foo();
  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Foo, SWIG_POINTER_NEW |  0 ); 
  return resultobj;
fail:
  return NULL;
}

在生成的python接口中,在python proxy class Foo 內部其實就是調用wrap_new_foo這個函數來生成一個新的SwigPyObject對象,而且把原生的Foo對象的指針包裹在本身的內部:ui

class Foo(_object):

    def __init__(self): 
        this = _foo.new_Foo()
        try: self.this.append(this)
        except: self.this = this

 Builtin type

 從Python Proxy Class的細節中,咱們能夠知道,一個Python對象調用原生的C++對象,其實是3層封裝:this

1 Python對象包含SwigPyObjectspa

2 SwigPyObject包含原生的C++的Foo對象指針

3 原生的C++的Foo對象code

層次越多效率越低,爲此在swig 2.0.4以後推出了一個Buitin type的特性。利用這個特性實現的Python類,能夠越過SwigPyObject這一層,直接包含原生的C++的Foo對象。經過減小封裝的層次,提升代碼的執行效率。對象

咱們能夠採用swig -builtin這個參數來激活這個特性。接口

經過swig -builtin參數生成的 wrap源代碼中有這樣的定義:

SWIGINTERN PyMethodDef SwigPyBuiltin__Foo_methods[] = {
  { "bar", (PyCFunction) _wrap_Foo_bar, METH_VARARGS, (char*) "" },
  { NULL, NULL, 0, NULL } /* Sentinel */
};

static PyHeapTypeObject SwigPyBuiltin__Foo_type = {
/*
省略成員的定義
*/
}

定義了一種新的python builtin類型 Foo_type,在python中,能夠直接調用Foo_type來操縱Foo*。

不過使用Builtin 特性有一些要注意的點:

1 python 2.3以前的版本不支持

2 不能直接調用函數接口,好比new_foo這樣的函數,而是直接調用Foo()

3 對象的靜態成員不須要用 .cvar.成員 , 而是直接用 類名.成員

本文的代碼可經過下面的連接下載:

https://dl.dropbox.com/u/35106490/swig6.tgz

相關文章
相關標籤/搜索