首页 > 解决方案 > 带有输出参数的 SWIG 回调

问题描述

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

CPP.h:

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

政协:

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

运行.py:

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

不幸的是,这段代码有段错误。director 文档提到了使用swig typesmaps,特别是directorin、directorout 和directorargout,遗憾的是没有示例。

我尝试了一些没有运气的事情。例如:

%apply int &DIRECTORARGOUT { int &val };

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

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

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

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

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

我想我可以通过让我想要的输出值(通常超过 1 倍)成为类的成员来尝试避免整个问题MyOp,但似乎应该有一个好方法来做到这一点,我会感谢您找到它的任何帮助。

标签: pythoncallbackswig

解决方案


cpointer.i解决方案对我有用。你必须展示一个最小的、完整的、可验证的例子来修复你的崩溃。我刚刚更改了以下文件:

CPP.i:

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

运行.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

推荐阅读