【问题标题】:Pass C++ object to Lua function将 C++ 对象传递给 Lua 函数
【发布时间】:2010-04-05 21:44:29
【问题描述】:

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

整个任务:

  1. 将一些类方法绑定到 Lua 状态机;
  2. 将类对象的引用传递给函数,用 Lua 编写;
  3. 在 Lua 函数中使用传递的 C++ 对象进行操作。

我已经找到了如何在 Lunar 上迈出第一步,但无法应付第二和第三步。

我不能使用 SWIG 和 boost。

【问题讨论】:

    标签: c++ lua


    【解决方案1】:
    //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 } 交易)。但是,如果您对此过程一无所知,这应该是一个起点。

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

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

    【讨论】:

    • 我错了,还是说 T 的析构函数永远不会被这种技术调用?据我了解,Lua 对 C++ 对象一无所知,只是调用free 来获取它所控制的内存,例如由lua_newuserdata 分配的内存。
    • 可以肯定的是,我确实遗漏了那部分。可能还有许多其他有用的部分。
    【解决方案2】:

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

    【讨论】:

    【解决方案3】:

    和 John 一样,我使用过 luabind 并推荐它。但是,由于您不能选择使用 boost,因此您可能会发现 list of libraries on this page 很有帮助。您可能还想查看DoItYourselfCppBinding page on the lua-users wiki

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

    【讨论】:

    • 我简直不敢相信,我需要一些库来进行如此简单的操作。
    • 请记住,您始终可以使用 Lua C API 并自己进行绑定。这些库使将 C++ 类绑定到 Lua 变得“更容易”。
    猜你喜欢
    • 2019-03-23
    • 2017-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-25
    • 2015-08-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多