lua-users home
lua-l archive

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


On Monday, July 07, 2014 04:04:39 PM Austin Einter wrote:
> Say we have three lua functions as below
> 
> lua_f1(arg1)
> lua_f2(arg1, arg2)
> lua_f3(arg1, arg2, arg3)
> 
> Now I want to write a generic C function, that can take lua function name
> and variable number of arguments and can execute the lua functions and
> return the return value.
> 
> Below C function can take multiple number of arguments
> int execute_lua_function(char *function_name, int arg1, ...)
> {
>     //get the arguments one by one and push it to stack before we call lua
> function
> }
> 
> I understand, in C we can write functions with variable number of arguments
> 
> Inside C function, can we find the type of an argument and its values in an
> iterative way, so that we can push the argument to stack.
> 
> If this can be implemented, then when I want to call lua_f1, I can write
> code in C as execute_lua_function("lua_f1", arg1), when I want to execute
> lua_f2, I can write code in C as execute_lua_function("lua_f2", arg1, arg2)
> and so on....

The C function would look something like:

    #include <stdarg.h>
    int execute_lua_function(lua_State *L, const char* function_name, ...) {
        int result;
        va_list args;
        va_start(args, function_name);
        lua_getglobal(L, function_name);
        lua_pushinteger(L, va_arg(args, int));
        lua_call(L, 1, 1);
        result = lua_tointeger(L, -1);
        lua_pop(L, 1);
        return result;
    }

But with actual error checking, among other things.

The tricky part is you must know the types of the argument. If you're only 
supporting a small set of known Lua functions, then you can create a C 
function for each Lua function that knows how many and what type of arguments 
to push on the stack.

To support calling an arbitrary function, you need to include information 
about the types of the arguments in addition to the name.

    #include <stdarg.h>
    int execute_lua_function(lua_State *L,
                             const char* function_name,
                             const char* format_list, ...) {
        va_list args;
        va_start(args, format_list);
        lua_getglobal(L, function_name);
        /* scan the format string and push arguments */
    }

And use it like:

    execute_lua_function(L, "lua_f3", "iis", 5, 10, "foo");

Each letter of the format is the type of the argument. It also tells you the 
number of arguments.

Being able to return any value other than just int is another issue that can 
be solved in a similar way.

-- 
tom <telliamed@whoopdedo.org>