默认情况下,SWIG 使用作为输出的 double* 参数做什么?
What does SWIG do by default with a double* argument that is an output?
这是我第一次接触 SWIG,我没有通过搜索找到任何有用的东西,这可能意味着我什至没有找到正确的方向。如果有人能帮我引导一下,那就太好了。
我有一个以 double* 作为参数并将其用作输出的 C 函数:
int myFunc(double* p, int len){
int i;
for(i=0; i<len; i++){
p[i] = (double)i;
}
return 0;
}
总结一下,我没有做任何棘手或自定义的事情,我只是让 SWIG 默认情况下做任何事情:
%module MyModule
%{
/* Includes the header in the wrapper code */
#include "MyModule.h"
%}
/* Parse the header file to generate wrappers */
%include "MyModule.h"
这一切都有效,因为它编译并构建了一个我可以加载的模块。但是,人们可能会合理地期望能够像这样从 Python 调用它,而我不能:
numbers = [0.0]*5
myFunc(numbers, 5)
SWIG 抱怨第一个参数的类型错误。我一直在阅读一个叫做 typemaps.i 的东西,它可以让你手动指定类型转换。这对于像这个例子这样的标准东西是必要的吗?如果有人能告诉我应该阅读什么或 Google 的目的,我将不胜感激。
使用内置类型作为 SWIG 的输入参数是自动处理的,但 SWIG 在输出参数方面需要一些帮助。下面是一个简单的方法。
请注意,%inline
是一种在 .i
文件中为其添加函数和 SWIG 包装器的方法,而不是制作头文件并使用 #include
和 %include
.这对小例子很有用。
参考:carrays.i
%module x
%include <carrays.i>
%array_functions(double,doubles)
%inline %{
int myFunc(double* p, int len)
{
int i;
for(i = 0; i < len; i++)
p[i] = (double)i;
return 0;
}
%}
输出:
>>> import x
>>> pd=x.new_doubles(10)
>>> pd
<Swig Object of type 'double *' at 0x0000000002235CC0>
>>> x.myFunc(pd,10)
0
>>> x.doubles_getitem(pd,0)
0.0
>>> x.doubles_getitem(pd,1)
1.0
>>> x.doubles_getitem(pd,9)
9.0
>>> x.delete_doubles(pd)
再多做一点工作,我们就可以使用类型映射获得更 Pythonic 的界面。下面一组 in/argout/argfree 类型映射从单个 Python 输入对象生成类型 C 参数。
%typemap(in)
定义如何将 Python 输入转换为输入参数。它检查整数对象并生成第二个参数 (len),然后使用 malloc
生成第一个参数。
%typemap(argout)
定义如何将输出参数转换为 Python 对象,并将其附加到 $result
.[=26= 表示的现有 return 值]
%typemap(free)
从 in
类型映射中释放分配的参数。
参考文献:Common typemap methods, Multi-argument typemaps
%module x
%include <exception.i>
%typemap(in) (double* p, int len) %{
if(!PyLong_Check($input))
SWIG_exception(SWIG_TypeError, "expected integer");
= PyLong_AsUnsignedLong($input);
= malloc( * sizeof(double));
%}
%typemap(freearg) (double* p, int len) %{
free();
%}
%typemap(argout) (double* p, int len) {
PyObject* list = PyList_New();
int i;
for(i = 0; i < ; ++i)
PyList_SET_ITEM(list, i, PyFloat_FromDouble([i]));
$result = SWIG_Python_AppendOutput($result, list);
}
%inline %{
int myFunc(double * p, int len)
{
int i;
for(i = 0; i < len; i++)
p[i] = (double)i;
return 0;
}
%}
输出:
>>> import x
>>> x.myFunc(5)
[0, [0.0, 1.0, 2.0, 3.0, 4.0]]
>>> return_value, double_list = x.myFunc(3)
>>> return_value
0
>>> double_list
[0.0, 1.0, 2.0]
这是我第一次接触 SWIG,我没有通过搜索找到任何有用的东西,这可能意味着我什至没有找到正确的方向。如果有人能帮我引导一下,那就太好了。
我有一个以 double* 作为参数并将其用作输出的 C 函数:
int myFunc(double* p, int len){
int i;
for(i=0; i<len; i++){
p[i] = (double)i;
}
return 0;
}
总结一下,我没有做任何棘手或自定义的事情,我只是让 SWIG 默认情况下做任何事情:
%module MyModule
%{
/* Includes the header in the wrapper code */
#include "MyModule.h"
%}
/* Parse the header file to generate wrappers */
%include "MyModule.h"
这一切都有效,因为它编译并构建了一个我可以加载的模块。但是,人们可能会合理地期望能够像这样从 Python 调用它,而我不能:
numbers = [0.0]*5
myFunc(numbers, 5)
SWIG 抱怨第一个参数的类型错误。我一直在阅读一个叫做 typemaps.i 的东西,它可以让你手动指定类型转换。这对于像这个例子这样的标准东西是必要的吗?如果有人能告诉我应该阅读什么或 Google 的目的,我将不胜感激。
使用内置类型作为 SWIG 的输入参数是自动处理的,但 SWIG 在输出参数方面需要一些帮助。下面是一个简单的方法。
请注意,%inline
是一种在 .i
文件中为其添加函数和 SWIG 包装器的方法,而不是制作头文件并使用 #include
和 %include
.这对小例子很有用。
参考:carrays.i
%module x
%include <carrays.i>
%array_functions(double,doubles)
%inline %{
int myFunc(double* p, int len)
{
int i;
for(i = 0; i < len; i++)
p[i] = (double)i;
return 0;
}
%}
输出:
>>> import x
>>> pd=x.new_doubles(10)
>>> pd
<Swig Object of type 'double *' at 0x0000000002235CC0>
>>> x.myFunc(pd,10)
0
>>> x.doubles_getitem(pd,0)
0.0
>>> x.doubles_getitem(pd,1)
1.0
>>> x.doubles_getitem(pd,9)
9.0
>>> x.delete_doubles(pd)
再多做一点工作,我们就可以使用类型映射获得更 Pythonic 的界面。下面一组 in/argout/argfree 类型映射从单个 Python 输入对象生成类型 C 参数。
%typemap(in)
定义如何将 Python 输入转换为输入参数。它检查整数对象并生成第二个参数 (len),然后使用 malloc
生成第一个参数。
%typemap(argout)
定义如何将输出参数转换为 Python 对象,并将其附加到 $result
.[=26= 表示的现有 return 值]
%typemap(free)
从 in
类型映射中释放分配的参数。
参考文献:Common typemap methods, Multi-argument typemaps
%module x
%include <exception.i>
%typemap(in) (double* p, int len) %{
if(!PyLong_Check($input))
SWIG_exception(SWIG_TypeError, "expected integer");
= PyLong_AsUnsignedLong($input);
= malloc( * sizeof(double));
%}
%typemap(freearg) (double* p, int len) %{
free();
%}
%typemap(argout) (double* p, int len) {
PyObject* list = PyList_New();
int i;
for(i = 0; i < ; ++i)
PyList_SET_ITEM(list, i, PyFloat_FromDouble([i]));
$result = SWIG_Python_AppendOutput($result, list);
}
%inline %{
int myFunc(double * p, int len)
{
int i;
for(i = 0; i < len; i++)
p[i] = (double)i;
return 0;
}
%}
输出:
>>> import x
>>> x.myFunc(5)
[0, [0.0, 1.0, 2.0, 3.0, 4.0]]
>>> return_value, double_list = x.myFunc(3)
>>> return_value
0
>>> double_list
[0.0, 1.0, 2.0]