Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python/SWIG:输出一个数组_Python_Return Value_Swig - Fatal编程技术网

Python/SWIG:输出一个数组

Python/SWIG:输出一个数组,python,return-value,swig,Python,Return Value,Swig,我试图从使用SWIG for Python包装的C函数输出一个值数组。我尝试的方法是使用以下类型映射 伪代码: int oldmain() { float *output = {0,1}; return output; } 类型映射: %typemap(out) float* { int i; $result = PyList_New($1_dim0); for (i = 0; i < $1_dim0; i++) { PyObject *o = PyFloat_

我试图从使用SWIG for Python包装的C函数输出一个值数组。我尝试的方法是使用以下类型映射

伪代码:

int oldmain() {
float *output = {0,1};
return output;
}
类型映射:

%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); 
 } 
} 
%typemap(out)float*{
int i;
$result=PyList_New($1_dim0);
对于(i=0;i<$1_dim0;i++){
PyObject*o=PyFloat_FromDouble((double)$1[i]);
PyList_SetItem($result,i,o);
} 
} 
我的代码编译得很好,但是当我运行access这个函数时它会挂起(没有更多的调试方法)

对我的错误有什么建议吗


谢谢。

这应该会让你开始:

/* example.c */

float * oldmain() {
    static float output[] = {0.,1.};
    return output;
}
您在这里返回一个指针,而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"
添加类型映射时,您可能会发现
-debug tmsearch
非常方便,即

swig -python -debug-tmsearch example.i

在为
float*oldmain
寻找合适的“out”类型映射时,应明确指出使用了您的类型映射。另外,如果您只想访问c全局变量数组,您可以使用
varout
的typemap执行相同的操作,而不只是
out

允许长度变化的最简单方法是添加另一个输出参数,该参数也会告诉您数组的大小:

%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;
}
%}
%模块测试
%包括
%typemap(in,numinput=0,noblock=1)大小{
尺寸模板;
$1=&templen;
}
%typemap(out)float*oldmain{
int i;
$result=PyList_New(模板);
对于(i=0;i

这将从修改为添加
size\u t*len
,可用于在运行时返回数组的长度。typemap完全隐藏Python包装器的输出,而是在
%typemap(out)
中使用它,而不是使用固定大小来控制返回列表的长度。

您可以共享Makefile或类似文件吗?你可能会发现Cython比SWIG更容易,除非你可以使用比Python更多的语言。谢谢,Oleksiy的回答解决了我的问题,但正如你所说,Cython似乎更容易,我正在探索这一点。再次感谢。嗨,非常感谢。这很有效。我试图将其推广到任意长度的数组,因此我使用$1_dim0而不是“2”,我遇到了这个问题(也可以在文档中找到)。示例_wrap.c:2979:error:'result_dim0'未声明(首次在此函数中使用)@seu-您不能这样做,因为数组的大小未知。返回类型是
float*
,而不是
float[2]
,这是
$1_dim0
要工作所必需的。@flex。谢谢我尝试使用“%typemap(out)float[ANY]{”正如在文档和它的编译中一样,但在Python中,我得到的返回值是。本质上,我试图返回一个长度可变的数组。有没有办法做到这一点,或者我总是必须知道长度?+1对于-debug tmsearch;我遇到了类似的问题,调试输出帮助我弄清楚我实际上想要编写一个数组n'argout'类型映射而不是'out'类型映射谢谢你的详细回答。我会试试这个。另一个问题:如果我的C代码中有一个变量或#define常量,这是我的输出数组长度,有没有办法用它来代替“templen”在你的例子中?@seu-最简单的方法就是将它插入到调用
PyList_New
的类型映射和
循环的
中。它似乎不起作用:我试图在我的c文件中定义一个常量,但我得到了以下错误
example_wrap.c:2980:错误:“arlength”未声明(首次用于此函数)
。我的目的是不再声明它,而是以某种方式能够访问此变量/常量。@SEU-您需要在类型映射之前执行
%{{包括“whatever.h”%}
,以使
ARRLENGTH
的定义在生成的包装器中可见。
%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;
}
%}