SWIG——在扩展内使用类型映射
Posted
技术标签:
【中文标题】SWIG——在扩展内使用类型映射【英文标题】:SWIG -- Using typemap inside of extend 【发布时间】:2014-02-11 01:21:53 【问题描述】:我编写了一个 c++ 类,并且正在使用 SWIG 制作我的类的 Python 版本。我想重载构造函数,以便它可以接收 Python 列表。例如:
>>> import example
>>> a = example.Array([1,2,3,4])
我试图在 swig 中使用 typemap 功能,但是 typemap 的范围不包括 extend 中的代码
这是一个与我所拥有的类似的例子......
%typemap(in) double[]
if (!PyList_Check($input))
return NULL;
int size = PyList_Size($input);
int i = 0;
$1 = (double *) malloc((size+1)*sizeof(double));
for (i = 0; i < size; i++)
PyObject *o = PyList_GetItem($input,i);
if (PyNumber_Check(o))
$1[i] = PyFloat_AsDouble(o);
else
PyErr_SetString(PyExc_TypeError,"list must contain numbers");
free($1);
return NULL;
$1[i] = 0;
%include "Array.h"
%extend Array
Array(double lst[])
Array *a = new Array();
...
/* do stuff with lst[] */
...
return a;
我知道 typemap 工作正常(我写了一个小测试函数,它只打印出 double[] 中的元素)。
我尝试将 typemap 放在 extend 子句中,但这并没有解决问题。
也许还有另一种在扩展中使用 Python 列表的方法,但我找不到任何示例。
提前感谢您的帮助。
【问题讨论】:
为什么需要类型映射? %extend 应该足以让您添加一个构造函数,该构造函数采用 std::list 和 std_list.i SWIG 将为您完成一切。 【参考方案1】:你真的很亲密:不是double lst[]
,而是扩展std::list<double>
:
%include "std_list.i" // or std_vector.i
%include "Array.h"
%extend Array
Array(const std::list<double>& numbers)
Array* arr = new Array;
...put numbers list items in "arr", then
return a; // interpreter will take ownership
SWIG 应该自动将 Python 列表转换为 std::list。
【讨论】:
我试图使用向量而不是列表(它一直说列表不是标准的一部分),当我输入a = example.Array([1,2.0,3])
时,它会抛出一个错误,说这不是可能的构造函数之一。尽管它说可能的构造函数之一是example::Array::Array(std::vector< double,std::allocator< double > > const &)
为什么这个答案会被接受?正如上面的评论,既不使用列表也不使用向量确实会导致一个构造函数被调用。
@kjyv 不幸的是,我现在还没有准备好深入研究这个问题,但是基于评论中的“一直说列表不是标准的一部分”,可能还有其他问题,比如编译器选项。我以前使用过这种技术,但已经有几年了,所以现在可能需要一个额外的 SWIG 选项等,我很想知道那里发生了什么。
我今天尝试了很多次,但遇到了同样的问题。一直说由于缺少命名空间 std 块而不会发生 std 的一部分。尽管如此,无论是使用列表还是向量,都不会调用该方法,并且我无法找到预期的签名。以上是关于SWIG——在扩展内使用类型映射的主要内容,如果未能解决你的问题,请参考以下文章
SWIG:如何使用 %apply 返回结构? “未定义类型映射”警告