python - SWIG 结构指针作为输出参数

标签 python c swig

我有一个结构:

struct some_struct_s {
   int arg1;
   int arg2;
};

我有一个 C 函数:

int func(some_struct_s *output);

两者都%include到我的 SWIG 文件中。

我希望将 some_struct_s *output 视为输出参数。 Python 示例:

int_val, some_struct_output = func()

“输出参数”包含在 POD 类型手册中(第 10.1.3 节),但不适用于非 POD 类型。

如何告诉 SWIG 我希望将 some_struct_s *output 作为输出参数?

最佳答案

来自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....

这是您的代码的完整示例(为简洁起见,没有错误检查):

%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;
}

%}

下面是演示。请注意,int 返回值为零以及作为元组的输出参数均以列表形式返回。

>>> import test
>>> test.func()
[0, (1, 2)]

如果您不需要类型映射,您还可以注入(inject)代码来创建对象并返回它以对用户隐藏它:

%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
%}

演示:

>>> 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

如果您仔细选择 SWIG 宏,则可以使类型映射语言变得不可知:

%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 {
    // The last parameter passes ownership of the pointer
    // to Python so it will be freed when the object's
    // reference count goes to zero.
    %append_output(SWIG_NewPointerObj($1, $1_descriptor, SWIG_POINTER_OWN));
}

%inline %{

struct some_struct_s {
   int arg1;
   int arg2;
};

int func(struct some_struct_s *output)
{
    output->arg1 = 1;
    output->arg2 = 2;
    return 0;
}

%}

演示:

>>> 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

关于python - SWIG 结构指针作为输出参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53387538/

相关文章:

c - C 中恰好一个字节的位掩码

c++ - SWIG:仅使用 header 和共享库为 Perl 包装 C++,无法定位可加载对象错误

java - 使用 SWIG 进行不兼容类型转换

php - wrap_newBundle 不可用 SWIG 和网络支付

python - 如果列表中的字符串因变音符号而失败

python - setuptools 与 virtualenv 的版本差异

python - 谷歌应用引擎 Python : get image upload size server-side

c - 当任何两个数字之和超过最大值时,C 程序计算如何或以什么程序运行?

c - 如何在 c 中处理此类消息 - 'objectFromFile' 的类型冲突

python - 运行子进程时检查条件