我正在尝试包装项目符号库的btVector3类的运算符+函数。运算符+不是定义为类成员,而是定义为函数。
包装运算符+=是一个类方法,工作正常。如果我在swig接口文件中声明运算符+(我只能在类定义之外声明),swig不会将其识别为属于该类的运算符。
我尝试使用extend:
%extend btVector3
{
btVector3 __add__(const btVector3& v1, const btVector3& v2) { return operator+(v1, v2); }
};
这导致swig为btVector3生成python __add__方法。然而,我确实得到了以下运行时错误:
AttributeError: 'module' object has no attribute 'btVector3___add__'
您尝试的问题是生成的__add__
函数是非静态的,因此实际上需要3个参数:(self, v1, v2)
。
通常,如果你想放弃self/this参数,你可以在C++中制作类似static
的东西。这在我刚刚使用SWIG/Python进行的测试中似乎不起作用。我认为这是因为Python中的类作用域函数,即使在使用特定实例而不是不使用实例进行调用时,也不会传入self
参数,因此它最终会缺少一个参数。
解决方案是将__add__
的%extend
版本编写为常规的旧成员函数。一个最小的例子:
%module test
%inline %{
struct btVector3 {
double v[3];
btVector3 add_vec(const btVector3& b) {
// Or call your other operator here instead.
btVector3 ret;
for (int i = 0; i < 3; ++i)
ret.v[i] = v[i]+b.v[i];
return ret;
}
};
%}
%extend btVector3 {
btVector3 __add__(const btVector3& b) {
btVector3 ret;
for (int i = 0; i < 3; ++i)
ret.v[i] = $self->v[i]+b.v[i];
return ret;
}
}
这足以让我像一样使用它
import test
print(dir(test))
a=test.btVector3()
b=test.btVector3()
c=a+b
print(c)