In the previous article(C calls lua function) describes how to call the lua function in C language. Usually, A can call the B language, and the other way around is true. Just as Java and C are used to intermodulate JNI, Lua and C can also be intermodulated.
When lua calls the c function, the same stack as c in lua is used. The c function gets the function from the stack and then pushes the result into the stack. To distinguish the returned result from other values in the stack, each function returns the number of results.
There is an important concept here: this stack is not a global structure, and each function has its own private local stack. Even if the c function calls the lua code, the lua code calls the c function again, and they have their own independent local stacks. The index of the first parameter is 1.
As the first example, let's see how to implement a simple function that returns the sum of given 2 parameters:
static int l_plus(lua_State* L)
{
lua_Integer a = lua_tointeger(L, 1);
lua_Integer b = lua_tointeger(L, 2);
lua_pushinteger(L, a+b);
return 1;
}
Every Lua registered function must be this prototype, which is already defined in:
typedef int (*lua_CFunction) (lua_State *L);
Since the c function returns a return number of int type return values. Therefore, when the return value is pushed, there is no need to clean the stack, lua will automatically remove any data below the return value.
Before using this function in lua, we need to register it. Use lua_pushcfunction, which accepts a c function and then creates a function type value inside lua to represent the function.
lua_pushcfunction(L, lua_plus);
lua_setglobal(L, "myplus");
A professional point is written in that we have to check its parameter types:
static int l_plus(lua_State* L)
{
lua_Integer a = luaL_checkinteger(L, 1);
lua_Integer b = luaL_checkinteger(L, 2);
lua_pushinteger(L, a+b);
return 1;
}
Complete code:
#include <>
#include <>
#include <>
static int l_plus(lua_State* L)
{
lua_Integer a = luaL_checkinteger(L, 1);
lua_Integer b = luaL_checkinteger(L, 2);
lua_pushinteger(L, a+b);
return 1;
}
int main()
{
lua_State *L = luaL_newstate();
luaL_openlibs(L);
lua_pushcfunction(L, l_plus);
lua_setglobal(L, "myplus");
if (luaL_dostring(L, "print(myplus(2,2))")) {
lua_close(L);
error("Failed to invoke");
}
lua_close(L);
return 0;
}
(over)