объект python на собственный указатель c++

Я играю с идеей использовать python в качестве встроенного языка сценариев для проекта, над которым я работаю, и большинство вещей работает. Однако я не могу преобразовать расширенный объект python обратно в собственный указатель С++.

Итак, это мой класс:

class CGEGameModeBase
{
public:
    virtual void FunctionCall()=0;
    virtual const char* StringReturn()=0;
};

class CGEPYGameMode : public CGEGameModeBase, public boost::python::wrapper<CGEPYGameMode>
{
public:
    virtual void FunctionCall()
    {
        if (override f = this->get_override("FunctionCall"))
            f();
    }

    virtual const char* StringReturn()
    {
        if (override f = this->get_override("StringReturn"))
            return f();

        return "FAILED TO CALL";
    }
};

Повышение обертывания:

BOOST_PYTHON_MODULE(GEGameMode)
{
    class_<CGEGameModeBase, boost::noncopyable>("CGEGameModeBase", no_init);

    class_<CGEPYGameMode, bases<CGEGameModeBase> >("CGEPYGameMode", no_init)
        .def("FunctionCall", &CGEPYGameMode::FunctionCall)
        .def("StringReturn", &CGEPYGameMode::StringReturn);
}

и код питона:

import GEGameMode

def Ident():
    return "Alpha"

def NewGamePlay():
    return "NewAlpha"


def NewAlpha():
    import GEGameMode
    import GEUtil

    class Alpha(GEGameMode.CGEPYGameMode):
        def __init__(self):
            print "Made new Alpha!"

        def FunctionCall(self):
            GEUtil.Msg("This is function test Alpha!")

        def StringReturn(self):
            return "This is return test Alpha!"

    return Alpha()

Теперь я могу нормально вызывать первые функции, выполнив следующие действия:

const char* ident = extract< const char* >( GetLocalDict()["Ident"]() );
const char* newgameplay = extract< const char* >( GetLocalDict()["NewGamePlay"]() );

printf("Loading Script: %s\n", ident);
CGEPYGameMode* m_pGameMode = extract< CGEPYGameMode* >( GetLocalDict()[newgameplay]() );

Однако, когда я пытаюсь преобразовать класс Alpha обратно в его базовый класс (последняя строка выше), я получаю ошибку повышения:

TypeError: No registered converter was able to extract a C++ pointer to type class CGEPYGameMode from this Python object of type Alpha

Я много искал в сети, но не могу понять, как преобразовать объект Alpha в его указатель базового класса. Я мог бы оставить его как объект, а использовать его как указатель, чтобы его мог использовать некоторый код, не поддерживающий python. Любые идеи?


person Lodle    schedule 30.08.2009    source источник


Ответы (3)


Благодаря Стефану из списка рассылки python C++, я пропустил

super(Alpha, self).__init__()

из вызова конструктора, что означает, что он никогда не создавал родительский класс. Думал, это будет автоматом :D

Единственная другая проблема, с которой я столкнулся, заключалась в сохранении нового экземпляра класса как глобальной переменной, иначе он был очищен, поскольку вышел за рамки.

Так счастлив сейчас

person Lodle    schedule 31.08.2009

Возможно, это не тот ответ, который вы ищете, но взгляните на ChaiScript для встраивания в ваше приложение C++.

Согласно их веб-сайту,

ChaiScript — это первый и единственный язык сценариев, разработанный с нуля с учетом совместимости с C++. Это основанный на ECMAScript встроенный функциональный язык.

ChaiScript не имеет метакомпилятора, зависимостей от библиотек, системных требований сборки и какого-либо устаревшего багажа. At может без проблем работать с любыми функциями C++, которые вы ему предоставляете. Не нужно явно говорить о каком-либо типе, он ориентирован на функции.

С помощью ChaiScript вы можете буквально начать писать сценарий своего приложения, добавив в программу три строки кода и вообще не изменяя шаги сборки.

person Indy9000    schedule 31.08.2009
comment
Это выглядит великолепно. Просто нужно что-то, что может быстро обернуть объекты С++. Я попробую сегодня вечером - person Lodle; 31.08.2009
comment
Это хорошо, за исключением того, что я не могу расширить классы, а затем поделиться этим указателем с С++ :( - person Lodle; 31.08.2009
comment
Лодле, как одному из разработчиков ChaiScript, мне было любопытно, не могли бы вы пояснить, что вам нужно делать с расширением классов? Вы можете создавать и совместно использовать функции как обратные вызовы между C++ и ChaiScript, если это может удовлетворить ваши потребности. - person lefticus; 01.09.2009
comment
@Lefticus, я отправляю электронное письмо на ваш сайт. - person Lodle; 01.09.2009
comment
@lefticus Посмотрите на documentcloud.github.com/underscore/#extend, это простой способ расширяющихся объектов и, вероятно, того, что ищет Лодл. В любом случае питон лучше. - person Arpegius; 03.07.2012

Ну не уверен, поможет ли это вам, но у меня была такая же проблема со скриптами на Lua. Мы создали объекты из Lua и хотели, чтобы какой-нибудь код на C++ обрабатывал объекты с помощью указателей. Мы сделали следующее:

  • весь объектный материал был написан на C++, включая конструкторы, деструкторы и фабричный метод;
  • код lua вызывал фабричный метод для создания объекта. этот фабричный метод 1) дал объекту уникальный идентификационный номер и 2) зарегистрировал его на карте С++, которая сопоставила идентификационные номера с собственными указателями;
  • поэтому всякий раз, когда lua собирался передать указатель коду C++, вместо этого он давал идентификатор объекта, и код C++ искал карту для нахождения фактического указателя по идентификатору.
person SadSido    schedule 31.08.2009
comment
это было бы нормально, но я хочу, чтобы скрипт расширял объект, что делает это не так хорошо - person Lodle; 31.08.2009