обернуть std :: vector <pointer *> в boost.python - PullRequest
3 голосов
/ 27 июля 2011

Из моих исследований кажется, что оборачивать std :: vector, который содержит типы указателей, не очень просто. Например:

std::vector<GameObject*>

Я посмотрел на Boost Python vector_index_suite, но он просто дает мне ошибку времени выполнения:

Ошибка типа: преобразователь to_python (по значению) не найден для типа C ++: GameObject *

Я уже выставил GameObject:

class_<GameObject>("GameObject") ...

Так что я понял, что это невозможно с готовым решением. Я должен сделать какую-то обертку? Может ли кто-нибудь просто помочь мне с того, с чего мне начать?

Ответы [ 3 ]

2 голосов
/ 02 апреля 2012

Способ исправить это - явно указать, что оболочка вашего класса применима и к типу указателя.

class_<GameObject, GameObject*>("GameObject") ...

1 голос
/ 02 февраля 2013

Не могу комментировать @jkp, но его намек помог мне.Мой минималистичный случай:

RenderWorld.h

class RenderWorld {
    public:
        ...
        void addEntity(RenderEntity* entity) {entities.push_back(entity);};
        std::vector<RenderEntity*> getEntities(void) {return entities;};
    private:
        std::vector<RenderEntity*> entities;
 };

RenderEntity.h

 class RenderEntity {
     public:
         int getID(void) {return 42;};
 };

python-exportage.py.h (компилируется в exported.pyd)

BOOST_PYTHON_MODULE(exported)
{
    class_<RenderWorld>("RenderWorld")
        .def("addEntity", &RenderWorld::addEntity)
        .def("getEntities", &RenderWorld::getEntities)
    ;

    class_<RenderEntity, RenderEntity*>("RenderEntity")
        .def("getID", &RenderEntity::getID)
    ;

    class_<std::vector<RenderEntity*> >("PyVec")
         .def(boost::python::vector_indexing_suite<std::vector<RenderEntity*> >())
    ;
}

мой сеанс Python:

>>> import exported
>>> world = exported.RenderWorld()
>>> world
<exported.RenderWorld object at 0x00000000024A0E58>
>>> e1 = exported.RenderEntity()
>>> e1
<exported.RenderEntity object at 0x000000000284DF48>
>>> e1.getID()
42
>>> world.addEntity(e1)
>>> world.getEntities()
<exported.PyVec object at 0x000000000234B1B0>  
>>> world.getEntities()[0]
<exported.RenderEntity object at 0x0000000002441F50>
>>> world.getEntities()[0].getID()
42
>>> e1 == world.getEntities()[0]
False

Примечание: RenderEntity* будет заключен в другойобъект.Посмотрите на эти адреса и последнюю проверку.Это логично с точки зрения c ++, но не в области python.

0 голосов
/ 27 июля 2011

Вы должны также обернуть свой GameObject класс. Это не будет работать, пока у вас не будет оболочки Python для объекта-члена. Если вы не хотите выставлять членов класса, вы можете опустить их и просто иметь непрозрачный объект.

Кроме того, boost :: python отлично работает с общими указателями. Это дает вам дополнительное преимущество безопасной обработки памяти. Есть ли шанс, что вы можете изменить std::vector<GameObject*> на std::vector<boost::shared_ptr<GameObject> >? Это будет работать намного лучше.

...