What does SWIG do by default with a double* argument that is an output? -
this first encounter swig, , i'm not finding useful searching, means i'm not looking in right direction. if me vectored, great.
i have c function takes double* argument , uses output:
int myfunc(double* p, int len){ int i; for(i=0; i<len; i++){ p[i] = (double)i; } return 0; }
to wrap it, didn't tricky or custom, let swig whatever default:
%module mymodule %{ /* includes header in wrapper code */ #include "mymodule.h" %} /* parse header file generate wrappers */ %include "mymodule.h"
this worked in compiled , built module can load. however, 1 might reasonably expect able call python this, , can't:
numbers = [0.0]*5 myfunc(numbers, 5)
swig complains first argument wrong type. i've been reading thing called typemaps.i lets specify type conversions manually. necessary standard example? i'd grateful if tell me should read or google for.
using builtin types input parameters swig handled automatically, swig needs output parameters. below simple way it.
note %inline
way add function , swig wrapper in .i
file instead of making header file , using #include
, %include
. it's small examples.
reference: carrays.i
%module x %include <carrays.i> %array_functions(double,doubles) %inline %{ int myfunc(double* p, int len) { int i; for(i = 0; < len; i++) p[i] = (double)i; return 0; } %}
output:
>>> import x >>> pd=x.new_doubles(10) >>> pd <swig object of type 'double *' @ 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)
with little more work, can more pythonic interface using typemaps. below set of in/argout/argfree typemaps generate type c parameters single python input object.
%typemap(in)
defines how convert python input input parameters. checks integer object , generates 2nd parameter (len), uses malloc
generate 1st parameter.
%typemap(argout)
defines how convert output parameters python object, , appends existing return value represented $result
.
%typemap(free)
frees allocated parameter in
typemap.
references: 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"); $2 = pylong_asunsignedlong($input); $1 = malloc($2 * sizeof(double)); %} %typemap(freearg) (double* p, int len) %{ free($1); %} %typemap(argout) (double* p, int len) { pyobject* list = pylist_new($2); int i; for(i = 0; < $2; ++i) pylist_set_item(list, i, pyfloat_fromdouble($1[i])); $result = swig_python_appendoutput($result, list); } %inline %{ int myfunc(double * p, int len) { int i; for(i = 0; < len; i++) p[i] = (double)i; return 0; } %}
output:
>>> 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]
Comments
Post a Comment