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_functions
carrays.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__