简体   繁体   English

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

[英]Passing existing C++ objects to Lua and calling the passed objects' member functions

I'm working on a little simulation project which uses Lua to drive the behavior of individual units (ants) and using Luabind to glue the C++ and Lua sides together. 我正在研究一个小的仿真项目,该项目使用Lua来驱动各个单元(蚂蚁)的行为,并使用Luabind将C ++和Lua的面粘合在一起。 Each individual ant (there are different types, derived from the base class Ant) has a Run() function, which calls the appropriate script; 每个单独的ant(有不同的类型,从基类Ant派生而来)都有一个Run()函数,该函数调用相应的脚本。 the script then carries out whatever actions need to be taken, calling the exposed class functions and possibly free functions. 然后,脚本执行需要采取的任何操作,调用公开的类函数,并可能调用自由函数。 I've gotten the Run function (in C++) to successfully execute the matching Run function in the Lua script (which just prints some text at the moment). 我已经获得了Run函数(在C ++中),可以在Lua脚本中成功执行匹配的Run函数(此刻该脚本仅打印一些文本)。

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

lua is just a manager class which retrieves the function from the script. lua只是一个管理器类,它从脚本中检索函数。 The above is calling the following in a Lua file: 上面在Lua文件中调用了以下内容:

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

And Luabind registration looks like this for the AntQueen class: 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)
    ];
}

The way it's set up now, ants are created, removed, and found through a simple factory/manager. 现在,通过简单的工厂/经理来创建,删除和发现蚂蚁,这是它的设置方式。 Each ant can be retrieved by calling static Ant* AntFactory::GetAntByID(const int ID) which just finds the ant in a hash map and returns a pointer to the ant. 可以通过调用static Ant* AntFactory::GetAntByID(const int ID)来检索每个蚂蚁,后者仅在哈希映射中找到该蚂蚁并返回指向该蚂蚁的指针。 What I'm trying to do is get Lua to be able to do something like the following: 我想要做的是让Lua能够执行以下操作:

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

The above is just a made up example, but hopefully it shows what I'm trying to achieve. 上面只是一个虚构的示例,但希望它可以显示我正在尝试实现的目标。 I don't want Lua to garbage collect the objects, because they are managed already on the C++ side. 我不希望Lua垃圾收集对象,因为它们已经在C ++端进行了管理。 While testing everything out, any attempt to do the following: 测试所有内容时,请尝试执行以下操作:

ant = GetAntByID(ID)

in Lua resulted in abort() being called and the program crashing and burning. 在Lua中导致调用abort()并使程序崩溃并刻录。

R6010
-abort() has been called

I just seem to be missing something with how everything gets shuttled back and forth (this is my first foray into gluing Lua and C++ together beyond toy programs). 我似乎在所有事物来回往返方面都缺少一些东西(这是我第一次尝试将Lua和C ++粘合在一起,而不是玩具程序)。 I'm pretty sure passing a plain pointer isn't the way to do it; 我很确定传递普通指针不是做到这一点的方法。 lightuserdata seems to be what I'm looking for, but it also has a bunch of restrictions. lightuserdata似乎是我要寻找的东西,但它也有很多限制。

So to sum up: What is going on here that causes abort to be called and how can I use Luabind/the Lua C API to get a pointer to a C++ object passed to Lua and call member functions on that pointer as if it were an object (without letting Lua garbage collect it)? 综上所述:发生了什么事情,导致abort被调用,如何使用Luabind / Lua C API获取指向传递给Lua的C ++对象的指针,并对该指针调用成员函数,就好像它是对象(不让Lua垃圾收集它)?

The solution to this problem seemed to be tied to the AntFactory class/member functions being static. 这个问题的解决方案似乎与AntFactory类/成员函数是静态的有关。 As soon as I switched from registering and using this: 一旦我停止注册并使用它:

//C++

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

//Lua

factory:CreateAnt(foo, bar)

to an instantiated object and regular member functions like this: 实例化对象和常规成员函数,如下所示:

//C++

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

//Lua

factory:CreateAnt(foo, bar)

everything worked with no problems at all (after also pushing the factory to the global table). 一切工作都没有问题(在将工厂推向全球市场之后)。 I think the reason for this is that trying to call static member functions on a non-instantiated C++ object fails due to Lua (or Luabind?) not being able to have an object to query for calls. 我认为这样做的原因是,由于Lua(或Luabind?)无法让对象查询调用,因此试图在未实例化的C ++对象上调用静态成员函数失败。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM