- Passing Tables to Lua Functions
- A use case that happens often is the passing of tables to and from Lua functions. How is that handled? There are a few idioms you see over and over again to make it happen. Before discussing the idioms, here's the code:
- The Lua Program
- Here's the Lua program. As you can see, function tweaktable receives a table argument, converts all values to upper case, counts the values, and puts all that info in a new table that's returned.
- function tweaktable(tab_in)
- local tab_out = {numfields=1}
- for k,v in pairs(tab_in) do
- tab_out.numfields = tab_out.numfields + 1
- tab_out[tostring(k)] = string.upper(tostring(v))
- end
- tab_out.numfields = tostring(tab_out.numfields)
- io.write("At bottom of callfuncscript.lua tweaktable(), numfields=")
- io.write(tab_out.numfields)
- print()
- return tab_out
- end
- print("Priming run")
- The C Program
- The C program is the same as all the others except stacking arguments to Lua is a little different, and recovering the table passed back from Lua is a little different. The Lua tweaktable() function takes a table as its one and only argument and passes back one table. It passes back a completely different table so there's absolutely no question of the changes being made by reference to the args rather than passback.
- Start by looking and running the code, and then we'll discuss some of the idioms that make it work...
- #include <lua.h> /* Always include this when calling Lua */
- #include <lauxlib.h> /* Always include this when calling Lua */
- #include <lualib.h> /* Prototype for luaL_openlibs(), */
- /* always include this when calling Lua */
- #include <stdlib.h> /* For function exit() */
- #include <stdio.h> /* For input/output */
- void bail(lua_State *L, char *msg){
- fprintf(stderr, "\nFATAL ERROR:\n %s: %s\n\n",
- msg, lua_tostring(L, -1));
- exit(1);
- }
- int main(void)
- {
- lua_State *L;
- L = luaL_newstate(); /* Create Lua state variable */
- luaL_openlibs(L); /* Load Lua libraries */
- if (luaL_loadfile(L, "callfuncscript.lua")) /* Load but don't run the Lua script */
- bail(L, "luaL_loadfile() failed"); /* Error out if file can't be read */
- if (lua_pcall(L, 0, 0, 0)) /* PRIMING RUN. FORGET THIS AND YOU'RE TOAST */
- bail(L, "lua_pcall() failed"); /* Error out if Lua file has an error */
- printf("In C, calling Lua->tweaktable()\n");
- lua_getglobal(L, "tweaktable"); /* Tell it to run callfuncscript.lua->tweaktable() */
- lua_newtable(L); /* Push empty table onto stack table now at -1 */
- lua_pushliteral(L, "fname"); /* Push a key onto the stack, table now at -2 */
- lua_pushliteral(L, "Margie"); /* Push a value onto the stack, table now at -3 */
- lua_settable(L, -3); /* Take key and value, put into table at -3, */
- /* then pop key and value so table again at -1 */
- lua_pushliteral(L, "lname"); /* Push a key onto the stack, table now at -2 */
- lua_pushliteral(L, "Martinez"); /* Push a value onto the stack, table now at -3 */
- lua_settable(L, -3); /* Take key and value, put into table at -3, */
- /* then pop key and value so table again at -1 */
- if (lua_pcall(L, 1, 1, 0)) /* Run function, !!! NRETURN=1 !!! */
- bail(L, "lua_pcall() failed");
- printf("============ Back in C again, Iterating thru returned table ============\n");
- /* table is in the stack at index 't' */
- lua_pushnil(L); /* Make sure lua_next starts at beginning */
- const char *k, *v;
- while (lua_next(L, -2)) { /* TABLE LOCATED AT -2 IN STACK */
- v = lua_tostring(L, -1); /* Value at stacktop */
- lua_pop(L,1); /* Remove value */
- k = lua_tostring(L, -1); /* Read key at stacktop, */
- /* leave in place to guide next lua_next() */
- printf("Fromc k=>%s<, v=>%s<\n", k, v);
- }
- lua_close(L); /* Clean up, free the Lua state var */
- return 0;
- }
- The preceding code yields the following output:
- slitt@mydesk:~$ ./callfunc
- Priming run
- In C, calling Lua->tweaktable()
- At bottom of callfuncscript.lua tweaktable(), numfields=3
- ============ Back in C again, Iterating thru returned table ============
- Fromc k=>fname<, v=>MARGIE<Fromc k=>lname<, v=>MARTINEZ<Fromc k=>numfields<, v=>3<
- slitt@mydesk:~$
来源: http://www.bubuko.com/infodetail-3007150.html