Передача существующих объектов C ++ в Lua и вызов функций-членов переданных объектов - PullRequest
1 голос
/ 24 декабря 2010

Я работаю над небольшим симуляционным проектом, в котором Lua управляет поведением отдельных юнитов (муравьев), а Luabind склеивает стороны C ++ и Lua.Каждый отдельный муравей (есть разные типы, производные от базового класса Ant) имеет функцию Run (), которая вызывает соответствующий скрипт;Затем сценарий выполняет все необходимые действия, вызывая открытые функции класса и, возможно, свободные функции.Я получил функцию Run (в C ++) для успешного выполнения соответствующей функции Run в Lua-скрипте (который в данный момент просто печатает некоторый текст).

void AntQueen::Run()
{
    lua->GetObject("QueenRun")(GetID());
}

lua - это просто класс менеджеракоторый извлекает функцию из скрипта.Вышесказанное вызывает следующее в файле Lua:

function QueenRun(ID)
    print("The Queen is running!")
    print(ID)
end

И регистрация Luabind выглядит следующим образом для класса AntQueen:

void Register(lua_State *luaState)
{
    using namespace luabind;
    module(luaState)
    [
        class_<AntQueen, Ant>("AntQueen")
        .def("Eat", &AntQueen::Eat)
        .def("ExtractLarvae", &AntQueen::ExtractLarvae)
        .def("GetMaxLarvaeProduced", &AntQueen::GetMaxLarvaeProduced)
        .def("GetNumAvailLarvae", &AntQueen::GetNumAvailLarvae)
    ];
}

При настройке теперь создаются муравьи, удалил, и нашел через простую фабрику / менеджер.Каждый муравей можно получить, вызвав static Ant* AntFactory::GetAntByID(const int ID), который просто находит муравья в хэш-карте и возвращает указатель на муравья.То, что я пытаюсь сделать, - это заставить Луа сделать что-то вроде следующего:

function QueenRun(ID)
    ant = GetAntByID(ID)
    larvae = ant:GetNumAvailLarvae()
    print(larvae)
    ant:Eat()
end

Выше приведен лишь выдуманный пример, но, надеюсь, он показывает, чего я пытаюсь достичь.Я не хочу, чтобы Lua собирал объекты мусором, потому что они уже управляются на стороне C ++.При тестировании всего, любая попытка сделать следующее:

ant = GetAntByID(ID)

в Lua приводила к вызову abort() и аварийному завершению работы программы.

R6010
-abort() has been called

Мне просто кажется, чточто-то упустить из-за того, как все движется туда-сюда (это мой первый опыт склеивания Lua и C ++ вместе с игрушечными программами).Я уверен, что передача простого указателя не способ сделать это;Кажется, я ищу lightuserdata, но у него также есть ряд ограничений.

Итак, подведем итог: что здесь происходит, что вызывает abort, и как я могу использовать Luabind/ API Lua C для получения указателя на объект C ++, переданного Lua, и вызова функций-членов для этого указателя, как если бы он был объектом (не позволяя Lua мусору собирать его)?

1 Ответ

0 голосов
/ 11 января 2011

Казалось, что решение этой проблемы связано со статическими функциями класса / члена AntFactory. Как только я перешел от регистрации и использования этого:

//C++

static int AntFactory::CreateAnt(foo, bar)
{}

//Lua

factory:CreateAnt(foo, bar)

для экземпляра объекта и обычных функций-членов, таких как:

//C++

int AntFactory::CreateAnt(foo, bar)
{}

//Lua

factory:CreateAnt(foo, bar)

все работало без проблем вообще (после того, как подтолкнул фабрику к глобальной таблице). Я думаю, что причина этого заключается в том, что попытка вызова статических функций-членов на необнаруженном объекте C ++ не удалась из-за того, что Lua (или Luabind?) Не может иметь объект для запроса вызовов.

...