0

Cヘッダーファイルに次の関数コンストラクターがあります。

int my_fun(int i, void *a, void *b, void *c);

いくつかのコンテキストを提供するために、使用方法を示す C コードの実装を提供します。

int error;
double *a, *b, *c;

int i = 1;
int num = 500;
int num_dim = 2;

a = (double *) calloc(num, sizeof(double));
b = (double *) calloc(num, sizeof(double));
if (num_dim >= 3)
   c = (double *) calloc(num, sizeof(double));
else
   c = 0

 error = my_fun(i,a,b,c);
 error = my_fun(i,NULL,b,NULL); /*read only b*/

これを SWIG インターフェイス ファイルに実装する方法を知りたいです。他のタイプのポインター戻り引数に使用typemaps.iしましたが、サポートしていないようですvoid*

4

1 に答える 1

3

SWIG が提供するファイルcarrays.iは、 によく適合しcallocます。マクロを使用し%array_functionsたり%array_class、C スタイルの配列をターゲット言語にラップするヘルパー関数を公開したりできます。(C を使用している場合でも、両方を使用できます)。my_funで単純なものを一度にラップして定義する次のインターフェイスを作成しました%include

%module test

%include "carrays.i"

%array_functions(double,DoubleArray)

%inline %{
  int my_fun(int i, void *a, void *b, void *c) {
    printf("my_fun: i=%d, a=%p, b=%p, c=%p\n",i,a,b,c);
    return 0;
  }
%}

より多くの型をサポートしたい場合は、インターフェイス ファイルcalloc(num, sizeof(double))にさらに追加する必要があります。%array_functionscarrays.i は、配列内の特定の値を取得および設定する関数、およびそれらを削除する関数も生成します。

その後、使用例は Python で次のようになります。

import test

i = 5
num = 500
num_dim = 2

a = test.new_DoubleArray(num)
b = test.new_DoubleArray(num)
c = None
if num_dim >= 3:
  c =  test.new_DoubleArray(num)

error = test.my_fun(i,a,b,c)
error = test.my_fun(i,None,b,None)

# Beware of the exceptions, you need a finally: really
test.delete_DoubleArray(a)
test.delete_DoubleArray(b)
test.delete_DoubleArray(c)

これを自分のシステムでコンパイルして実行しました。

swig -python -Wall test.i
gcc -fPIC -I/usr/include/python2.7 test_wrap.c -shared -o _test.so -Wall -Wextra
LD_LIBRARY_PATH=. python2.7 run.py

次の出力が得られました。

my_fun: i=5、a=0x2767fa0、b=0x2768f50、c=(nil)
my_fun: i=5、a=(nil)、b=0x2768f50、c=(nil)

ここでの「配列」は、C で割り当てられたメモリの実際のチャンクへのプロキシにすぎcallocないため、配列に加えた変更は、次に読むときに Python から表示されます。


Python コードの%array_class代わりに使用すると、次のようになります。%array_functions

import test

i = 5
num = 500
num_dim = 2

a = test.DoubleArray(num)
b = test.DoubleArray(num)
c = None
if num_dim >= 3:
  c =  test.DoubleArray(num)

error = test.my_fun(i,a.cast(),b.cast(),c.cast() if c else None)
error = test.my_fun(i,None,b.cast(),None)

ここでは、参照カウントによって配列を明示的に削除する必要がなくなり、参照カウントを延期することで例外の問題を解決していることに注意してください。はandの%array_class実装も提供するため、Python の他の配列やコンテナーと同様に添え字を付けることができます。(ただし、C のように境界チェックはありません)__getitem____setitem__

于 2012-07-11T06:55:27.210 に答える