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

时间:2019-06-06 15:30:49

标签: python c++ swig

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()’

请注意,生成吸气剂的方法相同。

如何告诉swig生成接受Foo *或Foo&的二传手?

谢谢, 巴勃罗

1 个答案:

答案 0 :(得分: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文件中的第一个声明/定义类型之前(不带副本的情况下)包括以下内容:

%feature("valuewrapper") Foo;

就是这样。