没有默认构造函数的对象成员的 Swig setter

Swig setter for an object member that has no default constructor

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?

谢谢, 巴勃罗

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 文件中,在第一个 declaration/definition 没有复制构造函数的类型之前的某处包含以下内容:

%feature("valuewrapper") Foo;

就是这样。