Обертывание std :: vector из boost :: shared_ptr в SWIG для Python

РЕДАКТИРОВАТЬ: Моя ошибка решена; объяснил в моем ответе.

У меня есть это:

std::vector < boost::shared_ptr < Entity > > entities;

и пытаюсь выставить через SWIG вот так:

%include "boost_shared_ptr.i"
%include "std_vector.i"

%shared_ptr(Entity)
%include <Entity.h>

namespace std {
    %template(EntityVector) vector<boost::shared_ptr<Entity> >;
};

%include <TheFileWithEntities.h>

Однако в Python сущности оказываются кортежем:

import MyModule
print type(MyModule.cvar.entities)
# Output: (type 'tuple')

Я искал это в Google, но не смог найти конкретных примеров того, как это обернуть. На одной странице был приведен небольшой пример упаковки для C #, но в моем случае это не помогло.

Любая помощь приветствуется.


person morrog    schedule 04.04.2011    source источник


Ответы (3)


У меня возникли трудности с получением последовательности объектов-указателей Python для автоматического преобразования в std::vector объектов-указателей. В настоящее время я (застрял) использую Swig 1.3; YMMV, если вы используете Swig 2. Уловка заключалась в том, чтобы создать в файле интерфейса Swig (с %template) не только вектор, и не только объект, но и объекты-указатели:

%include "std_vector.i"
%template(myObjectT) namespace::of::myObject<T>;
%template(myObjectPtrT) boost::shared_ptr<namespace::of::myObject<T> >;
%template(myObjectVectorT) std::vector<boost::shared_ptr<namespace::of::myObject<T> > >;

Без myObjectPtrT Swig, похоже, не знает достаточно, чтобы преобразовать последовательность указателей Python в myObjectT в myObjectVectorT.

ОБНОВЛЕНИЕ: по какой-то причине я еще не смог понять, это приводит к невозможности вызывать методы на myObjectT из myObjectPtrT, хотя я также использовал SWIG_SHARED_PTR(myObjectT, myObject<T>).

person Paul Price    schedule 03.10.2011
comment
Я должен упомянуть, что наш проект перешел с SWIG на pybind11, что гораздо менее непонятно. - person Paul Price; 10.04.2018

См. Как предоставить std :: vector ‹int› как список Python с использованием SWIG?, вероятно, полезную информацию

person sehe    schedule 04.04.2011
comment
Спасибо за ответ, но, как вы можете видеть в моем вопросе, я уже знаю, как обернуть std :: vector. Проблема заключается в упаковке std :: vector из boost :: shared_ptr. SWIG, кажется, представляет его как кортеж, потому что он не может определить его часть shared_ptr. - person morrog; 05.04.2011
comment
Да, спасибо, я читал это, но не нашел ничего подходящего. Опять же, я могу обернуть boost :: shared_ptr и std :: vector, и они будут работать, как ожидалось. Проблема конкретно в std :: vector ‹boost :: shared_ptr‹ Entity ››, который отображается в Python как кортеж. Python может получить доступ к кортежу, просматривать вещи внутри него, управлять отдельными объектами внутри кортежа, но он не может добавлять или изменять его ... потому что это кортеж. - person morrog; 05.04.2011
comment
Я выяснил проблему и отредактировал свой вопрос с решением. Спасибо, что нашли время помочь! - person morrog; 05.04.2011

SWIG, похоже, оборачивает глобальные переменные типа std :: vector в кортежи. Решение состоит в том, чтобы переместить сущности в класс и получить к нему доступ через экземпляр этого класса. Пример:

class Globals
{
public:
     std::vector < boost::shared_ptr < Entity > > entities;
};

extern Globals globals;
person morrog    schedule 05.04.2011