lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


It was thus said that the Great Alexander Gladysh once stated:
> Hi, list!
> 
> I want to bind to Lua a third-party argv function, taking a list of
> strings as input:
> 
>     foo * bar(baz * pSelf, int argc, char ** argv, size_t * argvlen);
> 
> In Lua:
> 
>     local result = obj:bar("forty", "-", "two")
> 
> The question: what is a best way write bindings for bar() in Lua C API?

  There are two approaches---one is to pass in a series of strings, the
other, an array of strings.  So, you have:

	result1 = obj:bar("one","two","three","four")
	result2 = obj:bar { "one" , "two" , "three" , "four" }

Okay, so let's handle both:

int luabar(lua_State *L)
{
  baz     *self;
  int      argc;
  char   **argv;
  size_t   arglen;
  int      rc;

  self = luaL_checkudata(L,1,BAZ);
  if (lua_istable(L,2))
  {
    argc = lua_objlen(L,2);
    if (argc > 0)
    {
      int i;

      argv = malloc(argc * sizeof(char *));
      if (argv == NULL) 
        luaL_error(L,"out of memory");
      
      for (i = 0 ; i < argc ; i++)
      {
        lua_pushinteger(L,i + 1);
        lua_gettable(L,2);
        argv[i] = luaL_checkstring(L,-1);
        lua_pop(L,1);
      }
    }  
    else
      argv = NULL; /* or else handle 0 strings however it works */
  }
  else
  {
    argc = lua_gettop(L) - 1;	/* adjust for self object */
    if (argc > 0)
    {
      int idx;
      int i;

      argv = malloc(argc * sizeof(char *));
      if (argv == NULL)
        luaL_error(L,"out of memory");
      
      for (idx = 2 , i = 0 ; i < argc ; i++ , idx++)
        argv[i] = luaL_checkstring(L,idx);
    }
    else
      argv = NULL;
  }

  rc = bar(self,argc,argv,&arglen);
  free(argv);
  lua_pushinteger(L,rc);
  return 1;
}

  You might need to adjust it a bit to fit your needs, but that's about how
I would do it.

  -spc (Relatively straightforward compared to some of the Lua bindings I've
	done for work ... )