Swig setter для члена объекта, у которого нет конструктора по умолчанию - PullRequest
2 голосов
/ 06 июня 2019

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 &?

Спасибо, Pablo

1 Ответ

1 голос
/ 07 июня 2019

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

Все, что вам нужно сделать, это включить в файл .i где-то перед первым объявлением / определением типа безКопия ctor следующая:

%feature("valuewrapper") Foo;

И это все.

...