tags:

views:

91

answers:

3

I have a function that takes a variable number of arguments in C that I want to pass to another lua function. In pure Lua I could do something like this

function foo(...)
    print(...)
end

How would I do the same thing if I were to implement the function in C?

Edit: I might have worded this poorly. What I want to do is write the function foo above, in C, using the Lua API, but I don't know how to pass the arguments I get off the Lua stack into print, because I don't know how many there are, and I can't find any way to check.

+2  A: 

All lua-callable C functions must be of type lua_CFunction:

typedef int (*lua_CFunction) (lua_State *L);

The lua_State can contain a variable number of arguments, as shown in §3.7 of the Lua 5.1 Reference Manual. You cannot use a 'normal' C vararg function.

schot
+1  A: 

After reading a little further down in schot's link I think I've answered my own question. lua_gettop will tell me the number of arguments passed in, so I know what needs to be pushed on to the stack for the inner function.

I just didn't expect the function to check the stack size to be called "gettop". I would have expected "checkstack" or something, but that does something else entirely.

Alex
`lua_gettop()` tells you the stack index of the top of stack. At the entry of the C function, that happens to correspond to the number of arguments passed.
RBerteig
+2  A: 

The way to check the number of arguments on the stack is using the lua_gettop() function.

Try the following from the C function:

lua_getfield(L, LUA_GLOBALSINDEX, "print");
lua_insert(L, 1);
lua_call(L, lua_gettop(L)-1, 0);

The lua_call() will pop all the arguments from the stack so if you want to preserve them you would need to adjust it slightly to make a copy of all the arguments.

int args=lua_gettop(L);
if(lua_checkstack(L, args+1))
{
  int i;
  lua_getfield(L, LUA_GLOBALSINDEX, "print");
  for(i=1;i<=args;i++)
    lua_pushvalue(L, i);
  lua_call(L, args, 0);
}
else
{
  return luaL_error(L, "cannot grow stack");
}
gwell