【问题标题】:How to pass a table parameter from lua to C++ through a lightuserdata object?如何通过 lightuserdata 对象将表参数从 lua 传递到 C++?
【发布时间】:2019-02-24 09:34:17
【问题描述】:

我注册了一个函数,该函数创建一个 Lightuserdata 供 C++ 和 lua 使用。当我使用简单的变量、整数和字符串进行测试时,这部分工作正常。当它是字符串和整数时,我可以在 lua 中创建我的 lightuserdata 而不会出错。但是,当我尝试使用表格时,它会变得更加复杂

std::string aString = lua_tostring(lua,-4);

第一个参数正确,因为它应该是一个字符串

if (lua_type(lua,-3 == LUA_TTABLE))  //is true so i know it recognizes it as a table
{
    auto t = lua_gettable(lua, -3);

    size_t tableLen = lua_rawlen(lua, -3); // also gives me the correct size
    lua_settop(lua, 1); //this discards the rest right? which i don't want.
    //luaL_checktype(lua, 1, LUA_TTABLE); //using this crashes the application expecting
// table but getting string
    lua_getfield(lua, 1, "a");
    lua_getfield(lua, 1, "b");
    lua_getfield(lua, 1, "c");
    lua_getfield(lua, 1, "d");
    lua_getfield(lua, 1, "e");
    std::cout << lua_gettop(lua) << std::endl; //after using the getfields i get the new table size 
//correctly (i assume, it turns 1 more value than expected, i think it's the table itself.
    //int a = luaL_checkinteger(lua, -5); //these don't work as they expect numbers but get nil
    //int b = luaL_checkinteger(lua, -4);
    //int c = luaL_checkinteger(lua, -3);
    //int d = luaL_checkinteger(lua, -2);
    //int e = luaL_checkinteger(lua, -1);
    std::cout << lua_tointeger(lua, -2) << std::endl; //returns always 0

}

尝试忽略表并获取堆栈的其余部分会在 0x000000 上给我一个违规错误,尽管第 3 个值正确调试为应有的值,而第 4 个值是空的,即使它正确传递,如果我不这样做' t 使用表格。

我正在尝试做的事情是这样的吗?

对正确方向的任何评论将不胜感激。 另外,如果我不知道表中键的名称,我应该使用什么?

【问题讨论】:

  • 我没有看到 C 代码,只有 C++
  • 抱歉更正了,因为它们非常相似,所以认为这并不重要
  • lua_getstring(lua,-4); 你使用的是哪个 Lua 版本?它一定是古老的东西,因为在 Lua 4.0 左右的某个地方没有 lua_getstring()
  • @Vlad 我重写了上面的代码,因为我有很多调试行,所以不想复制粘贴所有内容。但你是对的。它是 lua_tostring。我正在使用 5.2
  • I can create my lightuserdata in lua - 不,你不能在 Lua 中创建它。它确实存在于 Lua 状态中,但只能由本机代码创建。 lightuserdata 本质上是一个指向不透明数据结构的普通指针。为什么要让它参与“通过 lightuserdata”的参数传递?

标签: c++ lua


【解决方案1】:

if (lua_type(lua,-3 == LUA_TTABLE)) //为真,所以我知道它会将其识别为表

这里有大错误,或者您没有发布实际代码。

您不是在检查索引 -3 下的值的类型,而是在询问索引 false 下的值的类型,因为 -3 == LUA_TTABLE 显然是 false

在“检查”之后发生的任何崩溃 - 都是此错误的结果。它会将任何不是nil 的内容识别为表格。

【讨论】:

  • 谢谢。很好,这就是我在代码中编写它的方式。由于某种原因,整个 if 语句运行,所以没有仔细检查它。虽然有进一步的测试。如果表格是序列类型 x = { 1,4,5,8,2},我可以使用表格:size_t count = lua_rawlen(lua, 1);for (i = 1; i &lt;= count; i++){lua_rawgeti(lua, 1, i);lua_rawgeti(lua, 1, i);int Top = lua_gettop(lua);std::cout &lt;&lt; lua_tonumber(lua, Top) &lt;&lt; std::endl;lua_pop(lua, 1);@ 987654332@ 将表格更改为 x = {a= 1, b= 4} 等会破坏事情。我似乎无法使用lua_len 获得表 len,返回 0 作为长度
  • 我接受了你的回答,因为在修复了 if 语句并测试了我之前测试过的东西之后,它起作用了。没有得到长度,因为那总是给我 0 但至少我可以使用 lua_next 遍历表并获取键值对。谢谢一堆。知道如何保留表格元素的顺序吗?
  • @Jimomo 长度仅为表的序列部分定义。而且你不能影响散列部分的迭代顺序。通常这完全没问题。
猜你喜欢
  • 2010-10-24
  • 2011-01-14
  • 1970-01-01
  • 1970-01-01
  • 2012-05-27
  • 1970-01-01
  • 2014-05-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多