当函数具有多个参数时阅读表格会导致错误。

我正在开发的库中的 Lua 函数内部尝试读取一个数组。

当我使用一个参数调用该函数时,例如:

xyz = {3, 4, 5}
setxyz(xyz)

我可以正确读取数组,但是如果我添加第二个参数

xyz = {3, 4, 5}
setxyz(xyz, 3)

程序就会崩溃。

问题出在 ReadXYZValue 函数内部的 lua_next 调用上,第一次进入该函数时程序就会崩溃。

我该如何修复它?

typedef struct {
  double x;
  double y;
  double z;
} XYZ;

// 在 Lua 中调用的函数
static int lua_ts_getxyz(lua_State *L)
{
  if (0 == L)
  {
    return 1;
  }
  int argumentsNumber = lua_gettop(L);
  XYZ xyz;
  bool res;
  res = ReadXYZValue(L, &xyz); // 此处存在问题
  if (false == res)
  {
    return 1;
  }
  double range;
  res = ReadNumericValue(L, &range);
  if (false == res)
  {
    return 1;
  }
  return 1;
}

bool ReadNumericValue(lua_State *L, double *range)
{
  if (false == lua_isnumber(L, 1))
  {
    return false;
  }
  *range = lua_tonumber(L, -1);
  return true;
}

bool ReadXYZValue(lua_State *L, XYZ *xyz)
{
  if (false == lua_istable(L, 1))
  {
    return false;
  }
  size_t tableSize = lua_rawlen(L, 1);
  if (tableSize != 3)
  {
    return false;
  }

  bool res = true;
  size_t i = 0;
  lua_pushnil(L);
  double llaArray[3];
  while (lua_next(L, -2) != 0) // 只包含数组时没有问题,有 2 个参数时就崩溃
  {
    if (lua_isnumber(L, -1))
    {
      llaArray[i] = lua_tonumber(L, -1);
      i++;
    }
    xyz->x = llaArray[0];
    xyz->y = llaArray[1];
    xyz->z = llaArray[2];
    lua_pop(L, 1);
  }
  return res;
}
点赞
用户258523
用户258523

栈索引 -2是lua C栈中第二个顶部元素。您的lua C函数的参数也在堆栈上。因此,当您获得两个参数时,您的堆栈是 <table>, <number>然后您推送一个空值,您的堆栈是 <table>, <number>, <nil>,并且 -2是数字。

您需要规范化您的堆栈,以使值在您期望的位置。

通常来说,一个好的习惯是使用正数引用C函数的参数,使用负数引用您手动添加到堆栈中的东西。

2015-06-03 14:15:20