SWIG 结构指针作为输出参数 [英] SWIG struct pointer as output parameter
问题描述
我有一个结构:
struct some_struct_s {int arg1;int arg2;};
我有一个 C 函数:
int func(some_struct_s *output);
两者都 %included
到我的 SWIG 文件中.
我希望将 some_struct_s *output
视为输出参数.Python 示例:
int_val, some_struct_output = func()
输出参数"包含在 POD 类型的手册中(第 10.1.3 节),但不适用于非 POD 类型.
如何告诉 SWIG 我希望 some_struct_s *output
成为输出参数?
来自 文档:
<块引用>11.5.7 争论"类型图
争论"typemap 用于从参数返回值.这最常用于为需要返回多个值的 C/C++ 函数编写包装器.争论"typemap 几乎总是与in"组合在一起.typemap---可能忽略输入值....
这是您的代码的完整示例(为简洁起见,没有错误检查):
%module 测试//声明一个输入类型映射,抑制需要任何输入和//声明一个临时堆栈变量来保存返回数据.%typemap(in,numinputs=0) some_struct_s* (some_struct_s tmp) %{$1 = &tmp;%}//声明一个输出参数类型映射.在这种情况下,我们将使用//一个保存结构数据的元组(没有错误检查).%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);%}//而不是头文件,我们将在内联声明此代码.//这包括包装器中的代码,以及告诉 SWIG//以目标语言创建包装器.%排队 %{struct some_struct_s {int arg1;int arg2;};int func(some_struct_s *输出){输出-> arg1 = 1;输出-> arg2 = 2;返回0;}%}
下面的演示.请注意,int
返回值为零以及作为元组的输出参数作为列表返回.
如果你不想要类型映射,你也可以注入代码来创建对象并返回它以对用户隐藏它:
%module 测试%rename(_func) 函数;//给包装器一个不同的名字%排队 %{struct some_struct_s {int arg1;int arg2;};int func(struct some_struct_s *output){输出-> arg1 = 1;输出-> arg2 = 2;返回0;}%}//声明你的接口%pythoncode%{定义函数():s = some_struct_s()r = _func(s)返回 r,s%}
演示:
<预><代码>>>>进口测试>>>r,s=test.func()>>>r0>>>秒<test.some_struct_s;<0x000001511D70A880处类型为'some_struct_s *'的Swig对象的代理>>>>s.arg11>>>arg22如果您仔细选择 SWIG 宏,您可以使类型映射语言不可知:
%module 测试%typemap(in,numinputs=0) struct some_struct_s *output %{$1 = malloc(sizeof(struct some_struct_s));%}%typemap(argout) struct some_struct_s* 输出 {%append_output(SWIG_NewPointerObj($1,$1_descriptor,1));}%排队 %{struct some_struct_s {int arg1;int arg2;};int func(struct some_struct_s *output){输出-> arg1 = 1;输出-> arg2 = 2;返回0;}%}
演示:
<预><代码>>>>进口测试>>>r,s=test.func()>>>r0>>>秒<test.some_struct_s;<0x000001DD0425A700 处类型为some_struct_s *"的 Swig 对象的代理>>>>s.arg11>>>arg22I 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_struct_s *output
to be treated like an output parameter. Python example:
int_val, some_struct_output = func()
"Output parameters" is covered in the manual for POD-types (sec 10.1.3), but not for non-POD types.
How do I tell SWIG I want some_struct_s *output
to be an output parameter?
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;
return 0;
}
%}
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 %{
struct some_struct_s {
int arg1;
int arg2;
};
int func(struct some_struct_s *output)
{
output->arg1 = 1;
output->arg2 = 2;
return 0;
}
%}
// 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) struct some_struct_s *output %{
$1 = malloc(sizeof(struct some_struct_s));
%}
%typemap(argout) struct some_struct_s* output {
%append_output(SWIG_NewPointerObj($1,$1_descriptor,1));
}
%inline %{
struct some_struct_s {
int arg1;
int arg2;
};
int func(struct some_struct_s *output)
{
output->arg1 = 1;
output->arg2 = 2;
return 0;
}
%}
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
这篇关于SWIG 结构指针作为输出参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!