没有默认构造函数的对象成员的 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的主要内容,如果未能解决你的问题,请参考以下文章

没有默认构造函数的成员对象的初始化列表

[ C++ ] C++类与对象之 类中6个默认成员函数

3-3:类与对象中篇——默认成员函数之构造函数和析构函数

c++之构造函数,析构函数(五千字长文详解!)

C++类和对象

C++类的特殊成员-默认/拷贝/移动构造函数