python - Use struct in SWIG argout typemap -
i want call c function python, should create , initialize struct. want struct converted python object return value in python.
here example files (based on accessing c struct array python swig) achieve want, i.e. create_struct()
creates , initializes struct, can used in python. john bollinger helping fix bugs.
example.h
#include <stdint.h> struct foo { uint8_t a[4]; }; void create_struct(struct foo** new_struct);
example.c
#include <string.h> #include "example.h" void create_struct(struct foo** new_struct){ struct foo* foo = (struct foo*) malloc(sizeof(struct foo)); uint8_t tmp[4] = {0,1,2,3}; memcpy(foo->a, tmp, 4); *new_struct = foo; }
example.i
%module example %{ #define swig_file_with_init #include "example.h" %} // define input , output typemaps %typemap(in) uint8_t a[4] { if (!pybytes_check($input)) { pyerr_setstring(pyexc_typeerror, "expecting bytes parameter"); swig_fail; } if (pyobject_length($input) != 4) { pyerr_setstring(pyexc_valueerror, "expecting bytes parameter 4 elements"); swig_fail; } uint8_t res[4]; char* bytes = pybytes_asstring($input); int i; (i=0; i<4; i++) { res[i] = (uint8_t) bytes[i]; } $1 = res; } %typemap(out) uint8_t a[4] { $result = pybytes_fromstringandsize((char*) $1, 4); } /* * fails "warning 453: can't apply (struct foo *output). no typemaps defined.": * %apply struct foo* output {struct foo* new_struct }; * i'm trying define typemaps struct foo* */ // typemap suppresses requiring parameter input. %typemap(in,numinputs=0) struct foo** new_struct (struct foo* temp) { $1 = &temp; } %typemap(argout) struct foo** new_struct { $result = swig_newpointerobj(*$1, $descriptor(struct foo*), swig_pointer_own); } %include "example.h" extern void create_struct(struct foo** new_struct);
setup.py
#!/usr/bin/env python3 distutils.core import setup, extension module1 = extension('example', sources=['example.c', 'example.i']) setup(name='example', version='0.1', ext_modules=[module1])
test.py
#!/usr/bin/env python3 import example foo = example.create_struct() print("foo.a: %r" % foo.a)
build , execute:
python3 setup.py build_ext --inplace && mv example.*.so _example.so && python3 test.py
the test code should print foo.a: b'\x00\x01\x02\x03'
.
Comments
Post a Comment