SWIG入門6:Python Proxy ClassとBuiltin Type

2539 ワード

前の文章では,SWIGの基本的な使い方をより高いレベルから説明した.この文章はSWIGのいくつかの実現の詳細に深く入り込むだろう.SWIGのデフォルトのパッケージ方式は、C/C++のstructとclassをPython Proxy Classにパッケージすることです.でもSWIG 2.0から4からswigは、Python Proxy Classよりも効率的にパッケージ化された新しいパラメータ-builtinを提供します.
Python Proxy Class
Python Proxy ClassはSWIGパッケージの重要な部分です.Python Proxy Classは、C/C++コードに自然にアクセスする方法を提供し、多くのSWIGの特性を提供します.このようなC++のコードがあれば、
class Foo {
public:
     int x;
     int spam(int);
     ...

SWIGはこのクラスのメンバー変数とメンバー関数をいくつかの簡単な関数にカプセル化します.例えばfoo_wrap.cxxには_が1つあります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オブジェクトのポインタを自分の内部に包みます.
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層パッケージであることがわかります.
1 PythonオブジェクトはSwigPyObjectを含む
2 SwigPyObjectオリジナルのC++を含むFooオブジェクト
3原生のC++のFooオブジェクト
階層が多ければ多いほど効率が低いため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_を直接呼び出すことができますタイプはFoo*を操作します.
ただし、Builtinプロパティを使用するには、次の点に注意してください.
1 python 2.3以前のバージョンではサポートされていません
2関数インタフェースを直接呼び出すことはできません.例えばnew_fooのような関数ではなく、直接Foo()を呼び出します.
3オブジェクトの静的メンバは不要である.cvar.メンバーではなく、直接クラス名を使います.メンバー#メンバー#
本明細書のコードは、次のリンクでダウンロードできます.
https://dl.dropbox.com/u/35106490/swig6.tgz