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

标签 c++ lua

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

整个任务:

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

我已经找到了如何使用 Lunar 迈出第一步,但无法应对第二步和第三步。

我不能使用 SWIG 和 boost。

最佳答案

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

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

关于c++ - 将 C++ 对象传递给 Lua 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2581377/

相关文章:

c++ - Linux 上 C++ std::condition_variable::notify_all() 上的段错误

c++ - MFC Tab 顺序以编程方式

c++ - 模板类并将数组初始化为零

lua - wrk 执行 Lua 脚本

erlang - 哪些编程语言支持热代码交换和/或沙箱处理?

从源代码编译 Lua 并用它创建 C 模块

c++ - 在 C++ 中获取指向 Lua 对象实例的指针

c++ - 使用带有自定义构造函数的 std::set 的自定义比较器

c++ - 所有的临时分配都有唯一的地址吗?

lua - 为什么短调用形式不适用于 Lua 5.3 中的表?