没有默认构造函数的对象成员的 Swig setter
Posted
技术标签:
【中文标题】没有默认构造函数的对象成员的 Swig setter【英文标题】:Swig setter for an object member that has no default constructor 【发布时间】:2019-06-06 15:30:49 【问题描述】:Swig 为没有默认构造函数的对象成员生成包装器代码。
要包装的代码:
class Foo
public:
Foo (int i);
;
Class Bar
public:
Bar(int i):foo(i)
...
Foo foo;
;
Swig Setter 生成:
SWIGINTERN PyObject *_wrap_Bar_foo_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args)
PyObject *resultobj = 0;
Bar *arg1 = (Bar *) 0 ;
Foo arg2 ; // -> swig generates a call to a non existing default constructor
...
然后,如果尝试编译包装器,我会收到一个错误,因为默认构造器不存在:
error: no matching function for call to ‘Foo::Foo()’
请注意,getter 生成采用相同的方法。
如何告诉 swig 生成一个接受 Foo* 或 Foo& 的 setter?
谢谢, 巴勃罗
【问题讨论】:
【参考方案1】:SWIG 从根本上很好地支持了这一点,实际上我无法用您展示的代码实际重现您所看到的内容。例如,这一切都有效:
%module test
%inline %
class Foo
public:
Foo (int i)
;
class Bar
public:
Bar(int i):foo(i)
Foo foo;
;
%
当使用 SWIG 3.0.2(现在已经很老了!)编译和运行时,我可以运行这个 Python 代码:
import test
f=test.Foo(0)
b=test.Bar(0)
b.foo=f
print('Well that all worked ok')
即使在更一般的情况下,这也可以工作的原因是feature known as the "Fulton Transform"。本质上,这旨在通过将其包装在另一个对象中来解决缺少复制构造函数的问题。 (尽管在特定情况下您已经表明它实际上并不需要)。
无论如何,虽然这应该自动应用,但在某些情况下它不能不会。幸运的是,即使它不能自动工作,你也可以强制它打开,使用%feature
您需要做的就是在您的 .i 文件中,在第一次声明/定义没有复制 ctor 的类型之前的某处包含以下内容:
%feature("valuewrapper") Foo;
就是这样。
【讨论】:
以上是关于没有默认构造函数的对象成员的 Swig setter的主要内容,如果未能解决你的问题,请参考以下文章