Binding Code To Lua |
|
By default, the Lua C API does almost no sanity checking of arguments passed to it. Passing incorrect stack indexes, for example, can result in segfaults or random data corruption.
You should always enable API checking in any debug build. You can do this by compiling with the option -DLUA_USE_APICHECK. luaconf.h uses this C macro to define luai_apicheck to call assert(); you can also edit this definition to do something possibly more useful.
The lauxlib.h interface provides functionality for exposing code to Lua and type checking any values passed. There is some LauxLibDocumentation. The following example is a fragment from lmathlib.c (Lua 4.0).
This is the sin function. luaL_check_number() is used to check the correct type of the sin function argument. lua_pushnumber() is used to return the sin calculated. Note, the return value of the math_sin() function is the number of values returned (lua functions can return many values).
#define PI (3.14159265358979323846)
static int math_sin (lua_State *L) {
lua_pushnumber(L, sin(TORAD(luaL_check_number(L, 1))));
return 1;
}
lua_mathlibopen() registers for us using luaL_openl(). The value of Pi is set and a tag method used to make the ^ binary operator generate powers of numbers.
settagmethod are no longer present in Lua 5.
static const struct luaL_reg mathlib[] = {
{"abs", math_abs},
{"sin", math_sin},
{"cos", math_cos},
... etc. (rest of table not included)
};
/*
** Open math library
*/
LUALIB_API void lua_mathlibopen (lua_State *L) {
luaL_openl(L, mathlib);
lua_pushcfunction(L, math_pow);
lua_settagmethod(L, LUA_TNUMBER, "pow");
lua_pushnumber(L, (LUA_NUM_TYPE)PI);
lua_setglobal(L, "PI");
}
luaL and examples of the Lua C API usage see the Lua's src/lib source files.
ToLua? - If there is a lot of information to bind then automating the process using a binding generator can help. toLua is one such tool. A package file is prepared, which is a cleaned up version of the C/C++ interface. See the toLua homepage for more details [1]. Another advantage of this technique is that less work may be required between Lua versions if the Lua C API changes significantly.
CPB - A simple, fast, and powerful binding library for the LUA scripting language. It takes the information from the compilers symbols and generates binding code directly from it. See the CPB [homepage] for more details.
SWIG - Simplified Wrapper and Interface Generator, it can generate bindings between your C/C++ code and a variety of scripting languages (Python, Perl, Tcl/Tk, Ruby, ...), includng Lua (>= 5.0). A big advantage might be that *one* interface file, similar to that used in tolua/tolua++, is used for bindings to all languages supported by SWIG. The SWIG web site is at [www.swig.org], see also the SWIG docs pertaining to Lua [2].
Function information can be exported from dynamically linked libraries. [FuBi] describes a method to call these functions from script (or RPC). This functionality can be used from Lua [3].