2014-12-20 9 views
2

내 루아 함수는 C 함수를 호출합니다. 그 중 하나는 아래처럼 매우 복잡합니다. 어떻게 모든 인수를 얻을 수 있습니까? C? 인수 colors{color, x, y} 구조체 유형 요소의 배열이며 숫자가 불확실합니다. 인수 region{x, y, width, height} 구조체 유형입니다. 내가 할 것이 무엇C 언어로 루아 함수의 복잡한 인수를 얻는 방법?

/* 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); 

    ...... 
} 
+0

주석이 달린 행에서 스택 맨 위에 3- 요소 배열이 있어야합니다. 값을 얻으려는 것처럼'lua_rawgeti'를 사용할 수 있고, 값을 얻기 위해'lua_tointeger'를 사용할 수 있습니다. (또한'# FFFFFF '와 같은 색상 리터럴은 바닐라 루아에 존재하지 않습니다) –

+0

루아의 색깔을 어떻게 표현하고 있습니까? 예를 들어'{EEEEEE, 30.0,30.0}'과 같이'# EEEEEE '는 무엇입니까? 그것은 문자열인가 아니면 rgb를 나타내는 정수입니까? – greatwolf

+0

이 시점에서 userdata를 조사해야합니다. 당신은 루아에 대해 좋은 메타 메서드를 제공하고 C로 실제 struct를 만들면 멋진 인터페이스를 얻을 수 있습니다. – dualed

답변

2

은 별도의 함수로 루아 테이블에서 pixel_t에 대한 처리 로직을 끊다입니다. 이렇게하면 코드를 더 입맛 맞추기 쉽고 추론하기가 더 쉬워집니다.

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에서 사용 단지 문제 : 루아의 C API를 서명 규칙을 다음 lua_topixel_t 같은 뭔가

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; 
    } 
} 
// ... 

주, 난 당신이 RGB를 표현하는 방법을 잘 모르겠어요 루아 쪽에서 색을 입혀서 여기에 그냥 정수라고 가정했습니다. 표현이 다른 경우, 예를 들어 루아 문자열과 같이 적절하게 lua_topixel_t을 수정하십시오.

+0

고맙습니다. @greatwolf, 내가 필요한 모든 코드를 보여 주셔서 감사합니다! – Suge