您尝试使用[ANY]
的想法不起作用有几个原因。尽管ANY
可以在类型映射中使用,以允许相同的类型映射使用不同的固定大小的数组,但这不是您在那里得到的。
C的语法并不是在那里要求的。你不能写:
int[4] bar() {
static int data[4];
return data;
}
或者:
int bar()[4] {
static int data[4];
return data;
}
在标准C.你可以得到最接近的是:
int (*bar())[4] {
static int data[4] = {1,2,3,4};
return &data;
}
但是,这并不是真的变得更容易包装。
然而,简单的解决方案可以由使用%array_class
工作,例如:
%module test
%inline %{
struct foo {
int member;
};
struct foo *bar() {
struct foo *arr = malloc(sizeof(struct foo) * 4);
for (int i = 0; i < 4; ++i)
arr[i].member = i;
return arr;
}
%}
%include <carrays.i>
%array_class(struct foo, fooArray);
这让我做的事:
Python 3.2.3 (default, May 3 2012, 15:54:42)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import test
>>> arr = test.fooArray.frompointer(test.bar())
>>> arr
<test.fooArray; proxy of <Swig Object of type 'fooArray *' at 0xb6f332a8> >
>>> arr[0]
<test.foo; proxy of <Swig Object of type 'struct foo *' at 0xb6f33038> >
>>> arr[1]
<test.foo; proxy of <Swig Object of type 'struct foo *' at 0xb6f33380> >
>>> arr[2]
<test.foo; proxy of <Swig Object of type 'struct foo *' at 0xb6f33398> >
>>> arr[3]
<test.foo; proxy of <Swig Object of type 'struct foo *' at 0xb6f330c8> >
>>>
我们可以去一步到位,但(可能)由注入代码以自动将指针转换为阵列类型,在SWIFT之前添加以下内容:bar()
:
%pythonappend bar() %{
# Wrap it automatically
val = fooArray.frompointer(val)
%}
所以,你现在可以使用它像:
Python 3.2.3 (default, May 3 2012, 15:54:42)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import test
>>> test.bar()[1].member
1
>>> arr = test.bar()
>>> arr[3].member
3
你必须要小心内存的所有权。在这些例子中,内存泄露了。您可以使用%newobject
来告诉SWIG内存是由Python方拥有的,但是它会在提早发布(只要原始返回值不再被引用),因此您需要安排保持原始值更长的时间。这方面的一个完整的例子,这节省了阵列类的实例内的原始指针保持周围只要阵列封装器的基准本身将是:
%module test
%pythonappend bar() %{
# Wrap it automatically
newval = fooArray.frompointer(val)
newval.ptr_retain = val
val = newval
%}
%newobject bar();
%inline %{
struct foo {
int member;
};
struct foo *bar() {
struct foo *arr = malloc(sizeof(struct foo) * 4);
for (int i = 0; i < 4; ++i)
arr[i].member = i;
return arr;
}
%}
%include <carrays.i>
%array_class(struct foo, fooArray);
注意虽然该阵列类这种生成是无界的,就像C中的struct foo*
一样。这意味着你不能在Python中迭代它 - 大小是未知的。如果大小真的是固定的,或者你有办法以某种方式知道大小,那么可以通过编写返回PyList的类型映射来更好地包装它(在我看来)。编写这段代码需要多一点工作,但是在Python方面看起来更好一些。
你看过这里吗? - http://stackoverflow.com/questions/8114030/swig-python-array-inside-structure – dpandiar 2012-08-17 02:33:55
@dpandiar - 这是一个非常不同的情况,因为大小是固定的和已知的,并且数组是成员而不是从函数返回值 – Flexo 2012-08-17 10:12:37