8

次の例のように、2 つの引数が指定されている C++ 関数があります。

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 側での回避策を知りたいです。誰でも助けてもらえますか?

4

1 に答える 1

10

非常に多くの場合 (例: int *n)、次のように書くだけで十分です。

%apply int *OUTPUT { int *n };

SWIG が出力パラメーターに提供するいくつかのデフォルトの型マップを使用します。(同様の INOUT と INPUT もあります)。

ただし、この例では、事前定義されたケースのいずれとも一致しないため、同じことを手動で行う必要があります。これは基本的に引数ごとに 2 つのタイプマップです。実際の関数呼び出し用に一時的なものを作成し、実際の入力の代わりにそれを使用する入力タイプマップと、結果を一時的なものから 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) は自動的に名前が変更され、明らかな名前の衝突が停止します。Python のタプル%append_outputの後ろに何かを追加するために展開する SWIG マクロです。$result関数fooに動的にメモリが割り当てられている場合は、それを処理する必要があります。freearg 型マップは、in 型マップが動的にメモリを割り当てる必要がある場合に便利です。

これは、次のようにコンパイルして実行するのに十分でした。

import test

len,str = test.foo()

print len
print str
于 2013-03-24T08:35:07.113 に答える