Calling C function from Lua
First, you need to create a lua_State*, where all Lua operations are done within it, by lua_open() (or you may use lua_newState() if you need to hook up your memory allocator to Lua.)
- lua_State* luaState= lua_open();
- function drawText(str, screenPosX, screenPosY);
- textWidth= drawText("Ready Go~", 240, 160);
We can get the values from the stack in C using an absolute index counting from the bottom of the stack (start from 1) or a relative index to the top of the stack (start from -1).
Then we can retrieve the values in stack inside the C function called by Lua with the following code:
- int drawText(lua_State* luaState)
- {
- float screenPosY = (float) lua_tonumber(luaState, -1); // get the value 160
- float screenPosX = (float) lua_tonumber(luaState, -2); // get the value 240
- const char* str = lua_tostring(luaState, -3); // get the value "Ready Go~"
- printf("Text '%s' draw at (%f, %f)\n", str, screenPosX, screenPosY);
- int textWidth= strlen(str);
- lua_pushnumber(luaState, textWidth); // return a value to Lua
- return 1; // number of values return to Lua
- }
when the C function exit, the stack will look like:
After Lua get the return value from the C function, the parameter and the return value of the C function will be popped out of the stack.
But before Lua can execute the drawText(), remember to register it to the lua_State* by:
- lua_register(luaState, "drawText", drawText);
Calling Lua functions from C
We can also call Lua functions from C. For example, we have declare a function in Lua script for initializing the engine configurations:
- function initEngineConfig(date)
- print('initialize engine on ' .. date);
- end
- lua_getglobal(luaState, "initEngineConfig"); // get the function to the stack
- lua_pushstring(luaState, "18th Aug, 2011"); // push the argument of the function
- lua_call(luaState, 1, 0); // execute the function
(You may also use lua_pcall() instead of lua_call() to get more debug info when error occurs)
The above C codes is equivalent to calling a function in Lua:
- initEngineConfig("18th Aug, 2011");
We can also use similar technique to execute an object's method in C. For instance, we can call an object's method in Lua:
- gameObjectA:update(timeSlice);
- gameObjectA.update(gameObjectA, timeSlice);
So, we need to push the 'update' function of 'gameObjectA' onto the Lua stack with 2 arguments:
- lua_getglobal(luaState, "gameObjectA"); // for getting the 'update' function of 'gameObjectA'
- lua_getfield(luaState, -1, "update"); // get the 'update' function of 'gameObjectA'
- lua_insert(luaState, -2); // swap the order of "gameObjectA" and "update"
- // so that "gameObjectA" becomes an argument
- lua_pushnumber(luaState, 1.0f/30.0f); // push the timeSlice argument on the stack.
- lua_call(luaState, 2, 0); // execute the functions.
Reference:
[1] Lua manual: http://www.lua.org/manual/5.1/manual.html
[2] Lua user data: http://www.lua.org/pil/28.1.html
[3] Lua light user data: http://www.lua.org/pil/28.5.html
[4] LUA_REGISTRY_INDEX: http://www.lua.org/pil/27.3.2.html