2

我的 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);

    ......
}
4

1 回答 1

2

我要做的是将pixel_tlua表的处理逻辑分解为一个单独的函数。这将使代码更可口,更容易推理。类似于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酌情修改。

于 2014-12-20T21:47:15.307 回答