将C ++对象传递给Lua函数

时间:2010-04-05 21:44:30

标签: c++ lua

我有一个C ++项目,其中1个类的1个方法经常更改。所以我想把代码从C ++转移到Lua。注意,我是Lua的新手。

整个任务:

  1. 将一些类方法绑定到Lua状态机;
  2. 将对象的引用传递给函数,用Lua编写;
  3. 使用Lua函数中传递的C ++对象进行操作。
  4. 我已经找到了如何使用农历第一步,并且无法应对第二和第三步。

    我无法使用SWIG和提升。

3 个答案:

答案 0 :(得分:8)

//This has a large number of steps, but I'm gonna post them all. This is all using native Lua 5 and the lua CAPI.
int CreateInstanceOfT(lua_State* L) {
    new (lua_newuserdata(L, sizeof(T))) T(constructor args);
    return 1;
}
int CallSomeFuncOnT(lua_State* L) {
    if (lua_istable(L, 1)) { // If we're passed a table, get CData
        lua_getfield(L, 1, "CData");
        lua_replace(L, 1);
    }
    if (!lua_touserdata(L, 1))
        lua_error(L); // longjmp out.
    T& ref = *(T*)lua_touserdata(L, 1);
    ref.SomeFunc(); // If you want args, I'll assume that you can pass them yourself
    return 0;
}
int main() {
    lua_State* L = luaL_newstate();
    lua_pushcfunction(L, CreateInstanceOfT);
    lua_setglobal(L, "CreateInstanceOfT");
    lua_pushcfunction(L, CallSomeFuncOnT);
    lua_setglobal(L, "CallSomeFuncOnT");
    luaL_dofile(L, "something.lua");
    lua_close(L);
}
-- Accompanying Lua code: semicolons are optional but I do out of habit. In something.lua
function CreateCInstance()
    local Instance = {
        CData = CreateInstanceOfT();
        SomeFunc = CallSomeFuncOnT;
    }
    return Instance;
end

local object = CreateCInstance();
object:SomeFunc(); // Calls somefunc.

我可以发布大量关于如何使曝光变得更容易,以及如何进行继承等的详细信息 - 如果你想暴露多个T,它还需要改变(我认为最常见的解决方案是一个简单的struct { std::auto_ptr<void>, int type }交易)。但是,如果你对这个过程一无所知,那应该是一个起点。

基本上,首先,我们要求Lua分配一些空间(userdata),然后将T放入其中。当CallSomeFuncOnT出现时,首先我们问它是否有一个表(许多Lua类基于表,因为它们支持面向对象,元表等),并获取用户数据,然后我们将其转换为指向我们的对象,然后转换为引用。请记住,lua_touserdata给你一个空白*,所以你最好还是确定另一端是什么。然后我们调用somefunc并返回。 在Main中,我们只将函数注册为全局变量。

现在,在Lua中,当您调用CreateInstanceOfT时,它实际上只是对Lua用户透明地调用T构造函数。然后我们在一个表中抛弃它,这对于Lua新手来说更简单,并通过传递它来调用SomeFunc。

答案 1 :(得分:1)

你看过luabind了吗?它使得将C ++对象和函数公开给LUA变得相当容易。

答案 2 :(得分:1)

和约翰一样,我使用过luabind并推荐它。但是,由于使用提升功能不适合您,您可能会发现list of libraries on this page很有帮助。您可能还想查看DoItYourselfCppBinding page on the lua-users wiki

页面上提到的一个库是oolua,它没有依赖关系(所以它说)。