lua-users home
lua-l archive

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


2011/3/24 Alexander Gladysh <agladysh@gmail.com>:
> I want to bind to Lua a third-party argv function, taking a list of
> strings as input:
>
> [...]
>
> The question: what is a best way write bindings for bar() in Lua C API?
>
> My current implementation is downright ugly: http://bit.ly/hw9Fpe
> (Called from here: http://bit.ly/dHJ5Vm)

You can simplify memory management in your implementation by
allocating a couple of userdata on the stack rather than using the Lua
allocator. lua_newuserdata will never return NULL, it will throw a
standard error instead. So your binding becomes:

static int lconn_command(lua_State * L)
{
  redisContext * pContext = check_connection(L, 1);

  const char ** argv = NULL;
  size_t * argvlen = NULL;
  int nargs;
  size_t i;

  // these 6 lines replace create_args and destroy_args
  nargs = lua_gettop(L);
  argv = (const char**)lua_newuserdata(L, nargs * sizeof(const char*));
  argvlen = (size_t*)lua_newuserdata(L, nargs * sizeof(size_t));
  for (i=0; i<nargs; ++i)
  {
    argv[i] = luaL_checklstring(L, i + 1, &argvlen[i]);
  }

  int nret = 0;
  int i = 0;

  redisReply * pReply = redisCommandArgv(pContext, nargs, argv, argvlen);
  if (pReply == NULL)
  {
    /* TODO: Shouldn't we clear the context error state after this? */
    return push_error(L, pContext);
  }

  nret = push_reply(L, pReply);

  freeReplyObject(pReply);
  pReply = NULL;

  return nret;
}