我的代码主要是在C ++中,但我想使用SWIG director选项在python中重新定义C ++虚函数,然后将该函数传递回C ++。以下是一个简化示例。
这是我在C ++中使用虚函数fun
的基类。 fun
接受(double* x, int n)
,它允许我将一个numpy数组传递给它。
class base{
public:
virtual double fun(double* x, int n){return 0.0;}
};
我有另一个接受这个基类的类:
class main{
public:
base* b_;
main(base& b){
b_ = &b;
}
};
这个类有一个构造函数,它接受一个基类并存储一个指向它的指针(b_
)。
我可以成功将swig接口编译成名为mymodule
的模块,确保启用导向器(请参阅下面的SWIG接口文件),并且根据SWIG导向器文档,我继承基类并重新定义虚拟接口函数fun
如下:
import mymodule
class base(mymodule.base):
def __init__(self):
super(base,self).__init__()
def fun(self,x):
return x[0]
然后我把它传递给main
类:
b = base()
m = mymodule.main(b)
然而,当我尝试m.b_.fun(array([1.,2.]))
时,我得到TypeError
:
TypeError: 'SwigPyObject' object has no attribute '__getitem__'
有关如何使其发挥作用的任何想法?我想当我将b
传递给mymodule.main时,C ++会将x
视为双*指针并且不知道如何处理它。
顺便说一句,这是我的swig界面文件:
%module(directors="1") mymodule
%{
#define SWIG_FILE_WITH_INIT
/* Includes the header in the wrapper code */
#include "myclasses.h"
%}
%feature("director") base;
%init %{
import_array();
%}
%apply (double* IN_ARRAY1, int DIM1) {(double* x, int n)};
/* Parse the header file to generate wrappers */
%include "myclasses.h"
答案 0 :(得分:0)
它看起来像Python的所有权问题。
提供SWIG的提示:
%new double *fun(double* IN_ARRAY1, int DIM1) {(double* x, int n)};
注意指向函数本身的指针。 当使用%new时,Python模块将为对象分配适当的所有权。这就是为什么你可以在调用中使用值而不是变量的原因。
答案 1 :(得分:0)
导演似乎没有认识到fun(double* x, int n)
的Python实现;它没有对该功能进行超载。
我怀疑原因是你的Python实现使用numpy作为参数。请注意,导演会调用抽象函数或实现抽象函数。
另一方面,%apply (double* IN_ARRAY1, int DIM1) {(double* x, int n)}
仅声明用于在Python中包装函数的typemap逻辑,而不是Director。请注意,这就是b.fun(array([1.,2.])
有效的原因!说,你应该向导演声明typemap逻辑。
在这里你可以找到如何做到这一点:
%typemap(directorin,numinputs=1) (double *x, int n)
{
npy_intp dim = $2;
$input = PyArray_SimpleNewFromData(1, &dim, NPY_DOUBLE, (void *)$1);
}
希望这能解决你的问题和其他未来的问题:)。我遇到了类似的问题,并花了几天时间试图找出答案。