3

私は、Python に取り込みたいグローバル変数配列を c に持っています。そして、私はvarouttypemap に問題があります:

/* example.c */
int foo[] = {0, 1};

そして、ここに非常にバニラのインターフェースがあります:

/* example.i */
%module example
%{     
 extern int foo[2];
%}

%typemap(varout) int foo[] {
  int i;
  //$1, $1_dim0, $1_dim1
  $result = PyList_New($1_dim0);
  for (i = 0; i < $1_dim0; i++) {
    PyObject *o = PyInt_FromLong((double) $1[i]);
    PyList_SetItem($result,i,o);
  }
}

%include "example.c"

次の SConstruct でビルドしようとすると:

import distutils.sysconfig
env = Environment(SWIGFLAGS='-python -shadow -Wall'.split(),
                  CPPPATH=[distutils.sysconfig.get_python_inc()],
                  SHLIBPREFIX="")
env.SharedLibrary('_example.so', ['example.c', 'example.i'])

$1_dim0特別な変数が設定されていないため、次のようなコンパイル不能なコードがexample_wrap.c.

SWIGINTERN PyObject *Swig_var_foo_get(void) {
  PyObject *pyobj = 0;

  {
    int i;
    //foo, , foo_dim1
    pyobj = PyList_New();
    for (i = 0; i < ; i++) {
      PyObject *o = PyInt_FromLong((double) foo[i]);
      PyList_SetItem(pyobj,i,o);
    }
  }
  return pyobj;
}

したがって、明らかに typemap の一致は発生していますが、配列の次元が欠落しています。私は何が欠けていますか?ディメンションのハードコーディングは機能します。

一般に、cvarswig でグローバル変数を拡張する方法はありますか?

$ swig -version
SWIG Version 2.0.4
Compiled with g++ [i686-pc-linux-gnu]
Configured options: +pcre
Please see http://www.swig.org for reporting bugs and further information
4

2 に答える 2

2

タイプマップはほぼvarout完成です。2つの小さな変更を加える必要があります。

  1. タイプマップにサイズANYを追加する必要があります。int foo[]

    %typemap(varout) int foo[ANY] {
      int i;
      //$1, $1_dim0, $1_dim1
      $result = PyList_New($1_dim0);
      for (i = 0; i < $1_dim0; i++) {
        PyObject *o = PyInt_FromLong((double) $1[i]);
        PyList_SetItem($result,i,o);
      }
    }
    

    これにより、タイプマップが、と同等であるだけでなく、(任意の)既知のサイズの配列と一致するようになりますint *foo

  2. size.cを変更して、サイズをfoo明確にする必要があります。現状では合法で正しいCですが、完全なCコンパイラでない限り、配列のサイズを推測するのは難しいです。次のように変更します。

    int foo[2] = {0, 1};
    

    タイプマップと一致することを確認するには十分varoutです。

これらの2つの変更により、生成されたコードは期待どおりに機能します。

SWIGINTERN PyObject *Swig_var_foo_get(void) {
  PyObject *pyobj = 0;

  {
    int i;
    //foo, 2, foo_dim1
    pyobj = PyList_New(2);
    for (i = 0; i < 2; i++) {
      PyObject *o = PyInt_FromLong((double) foo[i]);
      PyList_SetItem(pyobj,i,o);
    }
  }
  return pyobj;
}

これらの変更によって私のマシンで生成されるものです。

于 2012-07-27T21:01:35.467 に答える
0

単純ではない型の配列をどうするかを考えている私のような人のために、これを行う1つの方法を次に示します。

非単純型:

typedef struct {
    int a;
    float b;
} Foo;

およびグローバル配列:

extern Foo *foov[40];

%typemap(varout) Foo *foov[ANY] {
    int i;
    $result = PyList_New($1_dim0);
    for (i = 0; i < $1_dim0; i++) {
        PyObject *o = SWIG_NewPointerObj($1[i], SWIGTYPE_p_Foo, 0);
        PyList_SetItem($result, i, o);
  }
}

見つけるのに永遠にかかったので、これを共有しただけで、この記事が役に立ちました。私の非単純型のSWIGバージョンを割り当てる方法を見つける必要がありました-ここに埋もれていることがわかりました:

http://www.swig.org/Doc2.0/Python.html#Python_nn64

于 2015-12-20T16:12:43.710 に答える