带有输出参数的 SWIG 回调

SWIG Callback with Output Parameters

我的目标是能够在 python 中定义一个函数来修改它的一个参数,然后将其作为回调函数传递给 C++ 驱动程序。我一直在尝试使用 SWIG 及其 director classes 来实现这一点。考虑以下最小示例:

CPP.h :

class MyOp {
public:
  virtual void SetVal(int& val) {val += 1;};
  virtual ~MyOp() {}
};
int Runner(MyOp *op);

CPP.cc:

#include "CPP.h"
int Runner(MyOp* op) {
  int val = 1;
  op->SetVal(val);
  return val;
}

CPP.i:

%module(directors="1") CPP
%{
#include "CPP.h"
%}
%feature("director") MyOp;
%include "CPP.h"

run.py:

import CPP
class PyOp(CPP.MyOp):
    def SetVal(self, val):
        val += 2
print(CPP.Runner(PyOp()))

不幸的是,这段代码有段错误。 director documentation makes a reference to using swig typesmaps,特别是 directorin、directorout 和 directorargout,遗憾的是没有示例。

我尝试了几件事,但没有成功。例如:

%apply int &DIRECTORARGOUT { int &val };

但这在编译时给了我一个警告:

CPP.i:7: Warning 453: Can't apply (int &DIRECTORARGOUT). No typemaps are defined.

并在 运行 时崩溃。有趣的是,使用 DIRECTOROUT 没有编译时警告,但也会崩溃。如果在 python 函数中打印出 val 的值:

class PyOp(CPP.MyOp):
    def SetVal(self, val):
        print(val)
        val += 2

可以看到val的类型是<Swig Object of type 'int *' at 0x1053f5de0>。于是想到用cpointer.i来修复。但即使尝试使用 intp_value 取消引用 val 也会导致崩溃。

我想我可以尝试通过让我想要的输出值(通常大于 1)成为 class MyOp 的成员来避免这整个问题,但看起来应该有一个很好的方法来做到这一点,如果您能帮助找到它,我将不胜感激。

cpointer.i 解决方案对我有用。您必须显示 minimal, complete, verifiable example 才能修复崩溃。我刚刚更改了以下文件:

CPP.i:

%module(directors="1") CPP
%{
#include "CPP.h"
%}
%feature("director") MyOp;
%include "cpointer.i"
%pointer_functions(int, intp);
%include "CPP.h"

run.py:

import CPP
class PyOp(CPP.MyOp):
    def SetVal(self, val):
        i = CPP.intp_value(val)
        i += 2
        CPP.intp_assign(val,i)
print(CPP.Runner(PyOp()))

输出:

C:\>run
3