c - 如何获取C语言中Lua函数的复杂参数?

标签 c lua lua-table lua-api

我的Lua函数会调用C函数,其中一个函数非常复杂,如下所示,我如何获取C中的所有参数?参数 colors 是一个 {color, x, y} 结构体类型元素的数组,其数量不确定。参数 region{x, y, width, height} 结构类型。

/* the function in Lua:
    findColors {
        colors={{#FFFFFF,0.0,0.0}, 
                {#EEEEEE,30.0,30.0}, 
                {#DDDDDD,20.0,40.0}},
        count=1, 
        region={10, 20, 100, 200}
     }
*/


typedef struct {
    int color;
    int x;
    int y;
} pixel_t;

static int findColorsProxy(lua_State *L)
{
    lua_settop(L, 1);
    luaL_checktype(L, 1, LUA_TTABLE);

    lua_getfield(L, 1, "colors");
    lua_getfield(L, 1, "count");
    lua_getfield(L, 1, "region");

    int colors_count = (int)lua_rawlen(L, -3);
    if (colors_count == 0) return 0;

    pixel_t *ps = NULL;
    for (int i = 0; i < colors_count; lua_pop(L, 1))
    {
        pixel_t *p_new = (pixel_t *)realloc(ret, sizeof(pixel_t));
        if (p_new == NULL) {
            if (ps != NULL) free(ps);
            return 0;
        }


        lua_rawgeti(L, 4, ++i);

        ... // I don't know what should I do next to get the pixels.
    }


    int count = (int)luaL_optinteger(L, -2, 0);

    int region_args_count  = (int)lua_rawlen(L, -1);
    if (region_args_count != 0 && region_args_count != 4) return 0;

    region_t rg;
    memset(&rg, 0, sizeof(region_t));
    for (int i = 0; i < region_args_count; lua_pop(L, 1))
    {
        lua_rawgeti(L, 4, ++i);
        int c = (int)luaL_checkinteger(L, -1);

        switch (i-1) {
            case 0:
                rg.x = c;
            case 1:
                rg.y = c;
            case 2:
                rg.width = c;
            case 3:
                rg.height = c;
        }
    }

    lua_pop(L, 3);

    ......
}

最佳答案

我要做的是将lua表中的pixel_t的处理逻辑分解为一个单独的函数。这将使代码更容易被接受并且更容易推理。类似 lua_topixel_t 遵循 lua 的 C api 签名约定:

bool lua_topixel_t(lua_State *L, int t, pixel *p)
{
  if (lua_type(L, t) != LUA_TTABLE) return false;
  if (!p) return false;

  int i = 0;
  lua_rawgeti(L, t, ++i);
  p->color = lua_tointeger(L, -1);
  lua_rawgeti(L, t, ++i);
  p->x = lua_tointeger(L, -1);
  lua_rawgeti(L, t, ++i);
  p->y = lua_tointeger(L, -1);

  lua_pop(L, i);
  return true;
}

现在只需在 findColorsProxy 中使用它即可:

pixel_t *ps = (pixel_t *) malloc(sizeof(pixel_t) * colors_count);
for (int i = 0; i < colors_count; lua_pop(L, 1))
{
  // ..., -3 = colors, count, region
  lua_rawgeti(L, -3, ++i);
  // ..., colors, count, region, -1 = color[i]
  if (!lua_topixel_t(L, -1, &ps[i - 1]))
  {
    free(ps); return 0;
  }
}
// ...

注意,我不确定你如何从 lua 端表示 rgb 颜色,所以在这里我只是假设它是一个整数。如果表示不同,例如 lua 字符串,请根据需要修改 lua_topixel_t 。

关于c - 如何获取C语言中Lua函数的复杂参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27578833/

相关文章:

c++ - Swig C++ Lua 通过引用传递类

lua - (错误)ERR错误编译脚本(新功能):user_script:2: '='附近应为 'local'

c - 如何在C中读取lua表

c - 单元测试实际过程

java - 我可以在不编译的情况下获得 C/C++/Java 代码的 XML AST 吗?

regex - 与 Lua 中的正则表达式组类似吗?

for-loop - 使用 for 循环搜索表(字符串名称)(在 Lua 中)

arrays - 如何将键值对象插入redis中的lua表

在c中将char转换为int

c - 如何在 MATLAB 中获取矩阵的指数?