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

我有一个 C++ 项目,其中一个类的1个方法经常更改。因此,我想将该代码从 C++ 转换为 Lua。请注意,我是 Lua 的新手。

整个任务:

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

我已经找到了如何使用 Lunar 完成第一步,但无法处理第二步和第三步。

我无法使用 SWIG 和 boost。

原文链接 https://stackoverflow.com/questions/2581377

点赞
stackoverflow用户130641
stackoverflow用户130641

你有没有看过 luabind?它可以很方便地将 C++ 对象和函数暴露给 LUA。

2010-04-05 22:06:54
stackoverflow用户18265
stackoverflow用户18265

像 John 一样,我曾使用过 luabind 并推荐它。但是,由于使用 boost 对你来说不是一个选择,你可能会在 此页面上列出的库的列表 上找到有用的信息。你可能还想查看 lua-users wiki 的 DoItYourselfCppBinding 页面

页面上提到的一个库是 oolua,它没有任何依赖(它是这样说的)。

2010-04-05 22:43:47
stackoverflow用户298661
stackoverflow用户298661
//这个过程包含很多步骤,但我会全部展示。这全部是使用 Lua 5 原生和 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)) { // 如果传入的是一个表格,获取C数据
        lua_getfield(L, 1, "CData");
        lua_replace(L, 1);
    }
    if (!lua_touserdata(L, 1))
        lua_error(L); // 立即退出
    T& ref = *(T*)lua_touserdata(L, 1);
    ref.SomeFunc(); // 如果您想传递参数,我假设您自己可以传递
    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);
}
-- 伴随的 Lua 代码:分号可选,但我习惯性地把它们都写上了。在 something.lua 中
function CreateCInstance()
    local Instance = {
        CData = CreateInstanceOfT();
        SomeFunc = CallSomeFuncOnT;
    }
    return Instance;
end

local object = CreateCInstance();
object:SomeFunc(); // 调用 somefunc。

如果您想让一些继承、暴露更多 T 等变得更简单,我可以提供更多细节 - 如果您想暴露多个 T,那它需要进行修改(我认为最常见的解决方案是一个简单的 struct { std::auto_ptr<void>, int type } )。但是,如果您不了解这个过程,那这个代码将是一个很好的起点。

基本上,首先我们要求 Lua 分配一些空间(userdata),然后在其中放入 T。当 CallSomeFuncOnT 调用时,首先我们要求它检查一下我们是否有一个表格(许多 Lua 类都是基于表格的,因为它们支持面向对象、元表等等),然后获取 C 数据,将其转换为指向我们的对象的指针,再将其转换为引用。请记住,lua_touserdata 给出一个 void*,所以您最好确切地知道另一端是什么。然后我们调用 somefunc 并返回。

在 Main 中,我们只是将这些函数注册为全局函数。

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

2010-04-05 23:06:58