带输出参数的SWIG回调

时间:2018-11-03 12:25:09

标签: python callback swig

我的目标是能够在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引用了使用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的倍数)成为类MyOp的成员来避免整个问题,但是似乎应该有一个好的方法为此,我们将不胜感激。

1 个答案:

答案 0 :(得分:1)

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