【问题标题】:Passing Lua function to C++将 Lua 函数传递给 C++
【发布时间】:2017-07-25 17:42:30
【问题描述】:

我正在用 C++ 制作一个 GUI。

我想要一个 Lua 脚本用 C++ 注册一个 Lua 函数,这样当 C++ 处理按钮点击时,C++ 会调用一个注册的 Lua 函数。

我使用以下 SO 帖子作为指南:http://stackoverflow.com/questions/4928973/how-do-you-pass-a-lua-function-to-a-c-function-and-execute-the-lua-function-seve

由于某种原因,我的更改无法正常工作。

这是我的 Lua 代码:

-- this is button.setClickEvent
function self.setClickEvent(eventFunction)
    uiButtonSetClickEvent(self.id, eventFunction)
end

function buttonClick()
    print("yay it worked!")
end

button.setClickEvent(buttonClick)

这是 C++ 代码

static int lua_uiButtonSetClickEvent(lua_State *L)
{
    int argumentsCount = lua_gettop(L);
    int argumentsMin = 2;
    if(argumentsCount < argumentsMin)
        cout << "Error at uiButtonSetClickEvent, incorrect number of arguments" << endl;

    double buttonId = lua_tonumber(L, 1);
    int event = luaL_ref(L, LUA_REGISTRYINDEX);

    long i = uiButtonGetIndex(buttonId);
    if(i != -1)
    {
        cout << "!!! Storing lua function reference" << endl;
        uiButtons[i].luaClickEvent = event;
        uiButtonSetClickEvent(buttonId, lua_uiButtonCallClickEvent);
    }

    return 0;
}

static void uiButtonSetClickEvent(double buttonId, void (&event)(double))
{
    long i = uiButtonGetIndex(buttonId);
    if(i != -1)
        uiButtons[i].clickEvent = event;
}

static void lua_uiButtonCallClickEvent(double buttonId)
{
    long i = uiButtonGetIndex(buttonId);
    if(i != -1)
    {
          lua_rawgeti( L, LUA_REGISTRYINDEX, uiButtons[i].luaClickEvent);

          if ( 0 != lua_pcall( L, 0, 0, 0 ) ) {
            printf("Failed to call the callback!\n %s\n", lua_tostring(L, -1));
            return;
          }

          uiButtons[i].luaClickEvent = luaL_ref(L, LUA_REGISTRYINDEX);
    }
}

一切都按预期发生,直到发生

结果是lua_uiButtonCallClickEvent 中的以下行出现分段错误:

lua_rawgeti( L, LUA_REGISTRYINDEX, uiButtons[i].luaClickEvent);

我注意到 SO 指南和我的实现之间的唯一区别是,不仅将 Lua 函数传递给 C++,而且还传递了 buttonId

不知道是不是参数偏移造成的问题。

引用 Lua 函数的整数是 3。

我曾尝试研究 Lua 参考手册,但没有成功。

我相信我正在寻找的解决方法是微不足道的,我希望你能提供帮助。

感谢您的阅读

【问题讨论】:

  • 在调用lua_rawgeti 时你的Lua 栈可能已经被销毁了? LUA_REGISTRYINDEX 不会变得无效,并且无效的索引只会导致 nil 被压入堆栈(因此 lua_pcall 应该会导致崩溃)。跨度>
  • 由于段错误,我无法在 lua_rawgeti 之后输出到控制台,所以它不是 lua_pcall,但它不仅仅是 lua_rawgeti,如果我在通过其指针调用 uiButtonCallClickEvent 时尝试使用任何 lua_* 函数, lua 因段错误而跌倒在地,所以在我通过它的指针调用 c++ 函数之前,似乎出了点问题。我正在使用 GLFW 库,这一系列事件源于鼠标按钮的 glfw 回调:'( glfw 可能是问题。这当然与额外的参数无关,因为我已经在没有 glfw 的情况下测试了我的代码并且它作品
  • 所以你是对的,lua 堆栈似乎已经无法访问了。

标签: c++ lua


【解决方案1】:

lua_close(L) 调用过早,破坏了 lua 栈。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-14
    • 2019-03-23
    • 1970-01-01
    • 2017-07-21
    • 1970-01-01
    • 1970-01-01
    • 2010-10-02
    • 1970-01-01
    相关资源
    最近更新 更多