将现有的C ++对象传递给Lua并调用传递的对象的成员函数

时间:2010-12-24 00:30:21

标签: c++ lua luabind

我正在开展一个小型模拟项目,该项目使用Lua来驱动单个单元(蚂蚁)的行为,并使用Luabind将C ++和Lua侧面粘合在一起。每个单独的ant(有不同的类型,派生自基类Ant)都有一个Run()函数,它调用适当的脚本;然后脚本执行需要采取的任何操作,调用公开的类函数和可能的自由函数。我已经使用Run函数(在C ++中)成功执行Lua脚本中的匹配Run函数(此时只打印一些文本)。

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

lua只是一个从脚本中检索函数的管理器类。以上是在Lua文件中调用以下内容:

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

对于AntQueen类,Luabind注册看起来像这样:

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)来检索每个ant,它只是在哈希映射中找到ant并返回指向ant的指针。我想要做的是让Lua能够做类似以下的事情:

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 / Lua C API获取指向传递给Lua的C ++对象的指针并调用成员函数那个指针好像是一个对象(不让Lua垃圾收集它)?

1 个答案:

答案 0 :(得分:0)

这个问题的解决方案似乎与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?)无法让对象查询调用。