从Lua调用C: 方式:C函数从栈中获取函数參数(第一个參数总是局部栈的索引1),将结果压入栈中,C函数须要返回结果数量。
每一个函数都有自己的局部私有栈
样例:static int l_sin(lua_State *L){ double d = lua_tonumber(L,1); //获取參数,索引为1(私有栈) lua_pushnumber(L,sin(d)); //压入结果 return 1; //返回结果的数量}注冊函数到Lua: 1、函数的原型: typedef int(*lua_CFunction)(lua_State *L) 在函数返回之前,Lua会自己主动删除栈中结果之下的内容 2、使用lua_pushcfunction(L,func) lua_setglobal(L,"mysin") 3、參数类型检查:将lua_tonumber(L,1)改成luaL_checknumber(L,1) 注冊函数模块: luaL_register:这个函数接收一些C函数及其名称,并将这些函数注冊到一个与模块同名的table中。
样例:C:static const struct luaL_Reg mylib[] = { {"dir",l_dir}, {NULL,NULL} //结尾}luaL_register(L,"mylib",mylib);Lua:require "mylib"print("mylib.mysin(10)",mylib.mysin(10))数组操作: void lua_rawgeti(lua_State* L,int index,int key) void lua_rawset(L,index,key) lua_rawgeti(L,t,key)等价于: lua_pushnumber(L,key) lua_rawget(L,t) lua_rawget类似于lua_gettable,差别在于raw能够绕过元表的index lua_rawseti(L,t,key)等价于: lua_pushnumber(L,key) lua_insert(L,-2) //将'key'放到前一个值的以下:由于rawset的规则是key在以下value在栈顶 lua_rawset(L,t) 这两个函数都是raw操作,比涉及元表的table訪问更快。 演示样例:
int l_map(lua_State *L){ int i,n; luaL_checktype(L,1,LUA_TTABLE); //第一个參数必须是一个table luaL_checktype(L,2,LUA_TFUNCTION); //第二个參数必须是一个函数 n = lua_objlen(L,1); //获取table大小 for(int i=1;i<=n;i++){ lua_pushvalue(L,2); //压入f lua_rawgeti(L,1,i); //压入t[i] lua_call(L,1,1); //调用f(t[i]) lua_rawseti(L,1,i); //t[i] = 结果,***rawseti设置后会清除栈顶的返回值 } return 0;}