SEU*_*SEU 6 python swig return-value
我试图从使用SWIG for Python包装的C函数输出一个值数组.我尝试的方法是使用以下typemap.
伪代码:
int oldmain() {
float *output = {0,1};
return output;
}
Run Code Online (Sandbox Code Playgroud)
类型表:
%typemap(out) float* {
int i;
$result = PyList_New($1_dim0);
for (i = 0; i < $1_dim0; i++) {
PyObject *o = PyFloat_FromDouble((double) $1[i]);
PyList_SetItem($result,i,o);
}
}
Run Code Online (Sandbox Code Playgroud)
我的代码编译得很好,但是当我运行访问这个函数时它会挂起(没有更多的方法来调试它).
关于我哪里出错的任何建议?
谢谢.
允许长度变化的最简单方法是添加另一个输出参数,该参数也告诉您数组的大小:
%module test
%include <stdint.i>
%typemap(in,numinputs=0,noblock=1) size_t *len {
size_t templen;
$1 = &templen;
}
%typemap(out) float* oldmain {
int i;
$result = PyList_New(templen);
for (i = 0; i < templen; i++) {
PyObject *o = PyFloat_FromDouble((double)$1[i]);
PyList_SetItem($result,i,o);
}
}
%inline %{
float *oldmain(size_t *len) {
static float output[] = {0.f, 1.f, 2, 3, 4};
*len = sizeof output/sizeof *output;
return output;
}
%}
Run Code Online (Sandbox Code Playgroud)
这是从这个添加的答案修改的size_t *len,可以用来在运行时返回数组的长度.类型映射完全隐藏了Python包装器的输出,而是使用它%typemap(out)而不是固定大小来控制返回列表的长度.
这应该让你去:
/* example.c */
float * oldmain() {
static float output[] = {0.,1.};
return output;
}
Run Code Online (Sandbox Code Playgroud)
你在这里返回一个指针,swig不知道它的大小.普通的$ 1_dim0不起作用,所以你必须硬编码或做其他魔术.像这样的东西:
/* example.i */
%module example
%{
/* Put header files here or function declarations like below */
extern float * oldmain();
%}
%typemap(out) float* oldmain {
int i;
//$1, $1_dim0, $1_dim1
$result = PyList_New(2);
for (i = 0; i < 2; i++) {
PyObject *o = PyFloat_FromDouble((double) $1[i]);
PyList_SetItem($result,i,o);
}
}
%include "example.c"
Run Code Online (Sandbox Code Playgroud)
然后在python中你应该得到:
>> import example
>> example.oldmain()
[0.0, 1.0]
Run Code Online (Sandbox Code Playgroud)
添加类型图时,您可能会发现-debug-tmsearch非常方便,即
swig -python -debug-tmsearch example.i
Run Code Online (Sandbox Code Playgroud)
应该清楚地表明在寻找合适的'out'类型映射时使用了你的typemap float *oldmain.此外,如果您只想访问c全局变量数组,您可以使用typemap varout而不是仅使用相同的技巧out.