SWIG提供的文件carrays.i与calloc
匹配良好。您可以使用宏%array_functions
或%array_class
来公开一些将C风格数组包装为目标语言的帮助器函数。 (即使你使用C,你仍然可以使用它们)。我做了以下接口封装,并与%include
定义了一个简单my_fun
一下子:
%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中看到。
如果您使用的%array_class
代替%array_functions
的Python代码变成:这里的引用计数已删除的需要
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)
通知明确删除的磁盘阵列,解决与例外的问题,通过推迟至参考计数。 %array_class
还提供了__getitem__
和__setitem__
的实现,因此它可以像Python中的任何其他数组或容器那样进行子脚本化。 (虽然没有界限,就像C一样)