1

我正在做一个小模拟项目,它使用 Lua 来驱动单个单元(蚂蚁)的行为,并使用 Luabind 将 C++ 和 Lua 端粘合在一起。每个单独的蚂蚁(有不同的类型,派生自基类 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)它只在哈希映射中找到蚂蚁并返回指向蚂蚁的指针。我想要做的是让 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 垃圾收集它)?

4

1 回答 1

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?)无法有一个对象来查询调用。

于 2011-01-11T04:26:55.270 回答