Swig Struct Pointer As Output Parameter
I have a struct: struct some_struct_s { int arg1; int arg2; }; I have a C function: int func(some_struct_s *output); Both are %included into my SWIG file. I want some_struc
Solution 1:
From the documentation:
11.5.7 "argout" typemap
The "argout" typemap is used to return values from arguments. This is most commonly used to write wrappers for C/C++ functions that need to return multiple values. The "argout" typemap is almost always combined with an "in" typemap---possibly to ignore the input value....
Here's a complete example for your code (no error checking for brevity):
%module test
// Declare an input typemap that suppresses requiring any input and// declare a temporary stack variable to hold the return data.
%typemap(in,numinputs=0) some_struct_s* (some_struct_s tmp) %{
$1 = &tmp;
%}
// Declare an output argument typemap. In this case, we'll use// a tuple to hold the structure data (no error checking).
%typemap(argout) some_struct_s* (PyObject* o) %{
o = PyTuple_New(2);
PyTuple_SET_ITEM(o,0,PyLong_FromLong($1->arg1));
PyTuple_SET_ITEM(o,1,PyLong_FromLong($1->arg2));
$result = SWIG_Python_AppendOutput($result,o);
%}
// Instead of a header file, we'll just declare this code inline.// This includes the code in the wrapper, as well as telling SWIG// to create wrappers in the target language.
%inline %{
struct some_struct_s {
int arg1;
int arg2;
};
int func(some_struct_s *output)
{
output->arg1 = 1;
output->arg2 = 2;
return0;
}
%}
Demo below. Note that the int
return value of zero as well as the output parameter as a tuple are returned as a list.
>>>import test>>>test.func()
[0, (1, 2)]
If you don't want typemaps, you can also inject code to create the object and return it to hide it from the user:
%module test
%rename(_func) func; // Give the wrapper a different name
%inline %{
structsome_struct_s {
int arg1;
int arg2;
};
intfunc(struct some_struct_s *output){
output->arg1 = 1;
output->arg2 = 2;
return0;
}
%}
// Declare your interface
%pythoncode %{
def func():
s =some_struct_s()
r = _func(s)
return r,s
%}
Demo:
>>>import test>>>r,s=test.func()>>>r
0
>>>s
<test.some_struct_s; proxy of <Swig Object of type 'some_struct_s *' at 0x000001511D70A880> >
>>>s.arg1
1
>>>s.arg2
2
You can make the typemap language agnostic if you carefully select SWIG macros:
%module test
%typemap(in,numinputs=0) structsome_struct_s *output %{
$1 = malloc(sizeof(struct some_struct_s));
%}
%typemap(argout) structsome_struct_s* output {
%append_output(SWIG_NewPointerObj($1,$1_descriptor,1));
}
%inline %{
structsome_struct_s {
int arg1;
int arg2;
};
intfunc(struct some_struct_s *output){
output->arg1 = 1;
output->arg2 = 2;
return0;
}
%}
Demo:
>>>import test>>>r,s=test.func()>>>r
0
>>>s
<test.some_struct_s; proxy of <Swig Object of type 'some_struct_s *' at 0x000001DD0425A700> >
>>>s.arg1
1
>>>s.arg2
2
Post a Comment for "Swig Struct Pointer As Output Parameter"