python - SWIG void * parameters -
i have 2 structs (from third party lib actually) in swig .i file follow form:
typedef struct my_struct { void* pparameter; unsigned long plen; } my_struct; %extend my_struct { my_struct() { my_struct *m= new my_struct(); m->pparameter = null; m->plen = 0; return m; } } typedef struct another_struct { char * another; unsigned long len; } another_struct; %extend another_struct { another_struct() { another_struct *p= new another_struct(); p->another = null; p->len = 0; return p; } unsigned long __len__() { return sizeof(another_struct); } }
the pparameter in my_struct void * because can char * or pointer struct (such another_struct). handling char * mapping simple using %typemap(in) void* = char*;
, attempt use struct fails. here's i'd see in python:
s = my_struct() = another_struct() s.pparameter = # should pass struct pointer s.pparameter = "some string" # or char pointer if provided
is possible? if not, need declare helper functions assign pointer values?
you can swig. you'll end writing fairly large if
pick how handle python input though, depending on how many types want handle. here's complete example of 2 typemaps you'll need:
%module test %typemap(in) void* pparameter (int res=0, void *other_struct=null) %{ int len; res = swig_convertptr($input, &other_struct, $descriptor(struct another_struct*), 0); if (swig_isok(res)) { fprintf(stderr, "struct\n"); $1 = reinterpret_cast< another_struct * >(argp1); len = sizeof(another_struct); } else if (pystring_check($input)) { $1 = pystring_asstring($input); len = strlen((const char*)$1); fprintf(stderr, "string\n"); } //else if (...) { //} else { swig_exception_fail(swig_typeerror, "some more details, see special typemap variables docs ideas"); } %} %typemap(memberin) void* pparameter %{ $1 = $input; //fobar $self $self->plen = len; %} %inline %{ typedef struct my_struct { void* pparameter; unsigned long plen; } my_struct; typedef struct another_struct { } another_struct; %} %extend my_struct { my_struct() { my_struct *m= new my_struct; m->pparameter = null; m->plen = 0; return m; } }
here in
typemap takes pyobject , figures out it. saves length local variable.
the memberin
typemap uses set void*
, length appropriately.
you might want consider making plen
immutable (see: %immutable
) people can't arbitrarily change pointer. you'll need consider memory ownership semantics of typemap in order avoid leaks or double frees.
Comments
Post a Comment