2013-03-03 8 views
8

私は、次の例のように2つの引数が与えられたC++関数を持っています。Python + SWIGで参照引数とポインタ引数を受け取る方法は?

void func(int& n, char** data) 
{ 
    *data = other_func1(); // returns a char array 
    n = other_func2(); // returns the length of the array 
} 

私は簡単にCまたはC++でこの機能を使用することができますが、私はSWIGで生成されたPythonモジュールからそれを呼び出すことができるのか分かりません。私は、例えば、std :: pairを返す別のC++関数を書く必要があると思います。しかし、可能であれば、私はPython側の回避策を知りたいと思います。誰でも助けてくれますか? SWIGは、出力パラメータを提供し、いくつかのデフォルトのタイプマップを使用しています

%apply int *OUTPUT { int *n }; 

:書くのに十分である場合(例えばint *n)のかなり多くの場合

答えて

8

。 (同様のINOUTとINPUTもあります)。

この例では、あらかじめ定義されたケースのどれにも一致しませんので、同じことを手動で行う必要があります。これは引数ごとに基本的に2つのtypemapです - 実際の関数呼び出しのために何かを一時的に作成し、実際の入力の代わりにそれを使用するinput typemapと一時的な結果からPythonへの結果を整列するargoutです。 Pythonの場合、複数の引数を返すためにタプルを使用するのが理にかなっています。

例:

%module test 

%typemap(in,numinputs=0) int& n (int temp) "$1 = &temp;" 
%typemap(in,numinputs=0) char **data (char *temp) "$1 = &temp;" 

%typemap(argout) char **data { 
    %append_output(PyString_FromString(*$1)); 
} 

%typemap(argout) int& n { 
    %append_output(PyInt_FromLong(*$1)); 
} 

%inline %{ 
    void foo(int& n, char **data) { 
    static char str[] = "Hello world"; 
    *data = str; 
    n = sizeof str; 
    } 
%} 

ポイントは注意する:

一時変数見かけの名前の衝突を停止し、自動的に名前が変更されます(int tempchar *temp)。 %append_outputは、拡大してPythonの$resultタプルの後ろに何かを追加するSWIGマクロです。あなたの関数fooに動的に割り当てられたメモリがあれば、それを処理する必要があります。 freearg typemapは、in typemapが動的にメモリを割り当てる必要がある場合に便利です。

これは私が同じようにそれをコンパイルして実行することを可能にするのに十分であった:

import test 

len,str = test.foo() 

print len 
print str