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&lt;double&gt;

%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&lt; double,std::allocator&lt; double &gt; &gt; const &amp;) 为什么这个答案会被接受?正如上面的评论,既不使用列表也不使用向量确实会导致一个构造函数被调用。 @kjyv 不幸的是,我现在还没有准备好深入研究这个问题,但是基于评论中的“一直说列表不是标准的一部分”,可能还有其他问题,比如编译器选项。我以前使用过这种技术,但已经有几年了,所以现在可能需要一个额外的 SWIG 选项等,我很想知道那里发生了什么。 我今天尝试了很多次,但遇到了同样的问题。一直说由于缺少命名空间 std 块而不会发生 std 的一部分。尽管如此,无论是使用列表还是向量,都不会调用该方法,并且我无法找到预期的签名。

以上是关于SWIG——在扩展内使用类型映射的主要内容,如果未能解决你的问题,请参考以下文章

SWIG:如何使用 %apply 返回结构? “未定义类型映射”警告

swig 啥时候需要类型映射?

Swig 类型映射内部构造函数到受保护

如何为指针引用定义 SWIG 类型映射?

SWIG - 包装到 C# 时 std::list 没有默认类型映射,我该怎么办?

如何为双指针结构参数应用 SWIG 类型映射