Calling Lua function from C++

Calling Lua function from c++ is very simple. Value passing between c++ and Lua goes through stack, Lua C API provides a convenience ways for you to call Lua function from C. To call Lua function, you need to specify:

1. Function Name.
2. Parameters of function call.
3. Return values expected ( Lua function support multiple results reture)

Let say my lua function name call f in last.lua, takes 2 parameters.

-- last.lua
function f (x, y)
    return (x^2 * math.sin(y))/(1 - x)
end

I perform function call from c++ like this:

//last.cc
# extern "C" {
# #include "lua.h"
# #include "lualib.h"
# #include "lauxlib.h"
# }  

int main()
{
    double z;
    lua_State *L = lua_open();
    luaL_openlibs(L);
    if (luaL_loadfile(L, "last.lua") || lua_pcall(L, 0, 0, 0)) {
        printf("error: %s", lua_tostring(L, -1));
        return -1;
    }

    lua_getglobal(L, "f");
    if(!lua_isfunction(L,-1))
    {
        lua_pop(L,1);
        return -1;
    }
    lua_pushnumber(L, 21);   /* push 1st argument */
    lua_pushnumber(L, 31);   /* push 2nd argument */

    /* do the call (2 arguments, 1 result) */
    if (lua_pcall(L, 2, 1, 0) != 0) {
        printf("error running function `f': %s\n",lua_tostring(L, -1));
        return -1;
    }

    /* retrieve result */
    if (!lua_isnumber(L, -1)) {
        printf("function `f' must return a number\n");
        return -1;
    }
    z = lua_tonumber(L, -1);
    printf("Result: %f\n",z);
    lua_pop(L, 1);
    lua_close(L);

    return 0;
}

Compile it with g++ like this:

g++ -o last{,.cc} -llua -ldl

The results:

Result: -12.158958

Brief explanation of the C++ codes above:
First, I trigger lua_getglobal to get the function name, then I push 2 parameters to stack. I make lua_pcall by telling Lua I have 2 params and expect 1 value return. Upon success, I retrieve the return value from the top of the stack.

calling c++ function from Lua, implement sleep function

You can’t call c function directly from Lua, you have to create a wrapper function that allows calling from Lua. In this post, shows a simple example to implement millisecond sleep function to Lua using nanosleep.

To allow function call from Lua script, your function must obey certain format. As variable passing from Lua to C and vice versa are through Lua Stack, therefore, the wrapper function must pass Lua State as the only parameter.
How about the real function call parameters? We can get it from the stack using lua_tonumber(), lua_tostring() etc. To return result of function call, we use lua_pushnumber(), lua_pushstring() etc. Because Lua function allows return more than 1 results, therefore you need tell Lua by returning an integer value.

    static int Function_Name (lua_State *L) {
      int i = lua_tointeger(L, 1);  /* get argument */
      /* carry on the procedures here ... */
      lua_pushinteger(L, sin(d));  /* push result */
      return 1;  /* number of results */
    }

We need to setup a library to contain your functions. By doing this, construct a static structure in array. Next, we load up our lib by calling luaL_openlib() and at last, to trigger a dofile().

Lets check out the sample codes on how to implement msleep function to Lua.

Continue reading