doe*_*toe 3 c++ python swig python-extensions
我正在使用 SWIG 创建一些我无法更改的 C++ 代码的 Python 接口。其中一个 C++ 类有一个构造函数,该构造函数创建一个尚未使用的部分初始化的对象,必须首先对其调用初始化函数。我想在 Python 中通过提供一个替代构造函数来解决这个问题,该构造函数可以同时完成两件事(获取和初始化)。假设在 C++ 中我有
class X {
public:
X() {...}
void init(T a) {...}
...
};
Run Code Online (Sandbox Code Playgroud)
在 C++ 中,我必须将 X 实例化为
X x;
x.init(a);
Run Code Online (Sandbox Code Playgroud)
在Python中我想做
x = X(a)
Run Code Online (Sandbox Code Playgroud)
我的解决方案是一个 hack,取决于目标语言和 SWIG 生成包装器代码的具体方式:在我的 .i 文件中,我有
%inline %{
X* new_X(T a) {
X* ret = new X();
ret->init(a);
return ret;
}
%nodefaultctor X;
class X {
public:
...
%extend {
%pythoncode {
def __init__(self, *args):
this = _modulename.new_X(*args)
try:
self.this.append(this)
except:
self.this = this
}
}
};
Run Code Online (Sandbox Code Playgroud)
这工作正常,但不是很令人满意:
这似乎是一个相对常见的用例,那么有人知道是否有标准方法?
V-master 目前的答案并不能按原样工作。但它可以发挥作用:
%ignore X::X();
// declaration of class X, e.g. %include X.h
%extend X {
X(T a) {
X* newX = new X();
newX->init(a);
return newX;
}
};
Run Code Online (Sandbox Code Playgroud)
诚然,这看起来有点可疑,但它确实有效,并且本质上是 SWIG 文档中的一个示例。
需要注意的是:
%extend 适用于 C 和 C++ 代码。它不会以任何方式修改底层对象——扩展仅显示在 Python 界面中。
因此,这实际上是创建一个方法(实际上甚至不是类方法),该方法创建 的新实例X,调用init(a)它并返回它。由于语法有点类似于构造函数,因此 SWIG 会将其包装起来。