https://www.codingnow.com/2000/download/lua_manual.html#lua_newstate
来自 lua5.1
lua_Stat* lua = luaL_newstate(); // 一个新的 lua 状态机
luaL_openlibs( lua ); // 加载标准lib
int my_fun_name( lua_State *L ) {
int argc = lua_gettop( L ); // 获得函数参数个数
for( int i=1; i <= argc; ++i ) { // 注意 =
// 以下函数使用的参数序号规则如下:
// 调用参数: A B C D
// 正序序号: 1 2 3 4
// 反序序号:-4 -3 -2 -1
// 但是参数入栈却是:
// --------->
// D C B A
// lua_toboolean
// lua_tocfunction
// lua_tointeger 这是 ptrdiff_t,表示为机器最大整数类型
// lua_tonumber 这是 double
// lua_topointer
// lua_tostring 等价于 lua_tolstring
// lua_tolstring
// lua_tothread
// lua_touserdata userdata 和 light userdata 公用这个函数
// 将指定位置的参数转成C语言数值格式(需要它本身就是数值,否则返回0 )
printf( "lua fun arg[index: %d, type: %d, type_name: %s] : %lf\n",
i, lua_type( L, i ), lua_typename( L, i ), lua_tonumber( L, i ) );
}
// lua_to* 函数只获得参数值,参数此时还在栈上
lua_pop( L, argc ); // 弹出所有参数
// 创建一个新的 table
lua_newtable( L ); // 栈 -3
lua_pushstring( L, "name" ); // 栈 -2 key
lua_pushstring( L, "参数啊" ); // 栈 -1 value
// 另一种形式:lua_setfield( L, -3, "name" ),通过参数这是 key
lua_settable( L, -3 ); // 通过栈来表示k&v,这会弹出 key(-2) & value(-1)
lua_setglobal( L, "t" ); // 弹出 栈-3(table),并将值设置到全局变量 't' 中
// 此时栈平衡
luaL_dostring( L, "print(t.name)" ); // 输出:参数啊
// table 遍历,记住格式就行,只有看源码才能知道为什么这么写
/* table 放在索引 't' 处 */
lua_getglobal( L, "t" );
int t = -2; // -2 是因为要 push 一个 nil
lua_pushnil(L); /* 第一个 key */
while (lua_next(L, t) != 0) {
/* 用一下 'key' (在索引 -2 处) 和 'value' (在索引 -1 处) */
printf("%s - %s\n",
lua_typename(L, lua_type(L, -2)),
lua_typename(L, lua_type(L, -1)));
/* 移除 'value' ;保留 'key' 做下一次迭代 */
lua_pop(L, 1);
}
// 要保持栈平衡,移除 table t
lua_pop(L, 1);
// 调用 lua 函数
// #define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, s)
// 注意 LUA_GLOBALSINDEX,表示全局范围
lua_getglobal(L, "f"); // 从全局范围内寻找将调用的函数 f,并入栈
lua_pushstring(L, "how"); // 第 1 个参数
lua_getglobal(L, "t"); // 获得 table t 的索引,并压入栈 <-----------------+
lua_getfield(L, -1, "x"); // 压入 t.x (栈位置-1就是table t) 的值(第 2 个参数 |
lua_remove(L, -2); // 从堆栈中移去 't' ------------------------注意 ---+
lua_pushinteger(L, 14); // 第 3 个参数
lua_call(L, 3, 1); // 调用 'f',传入 3 个参数,并索取 1 个返回值
lua_setglobal(L, "a"); // 将最后一个栈数据弹出(也就是函数返回值)并设置到全局变量 'a' 中
// table 的索引,为什么称“索引”,记住这个概念即可
// 这些函数都有对应的 check 函数:lua_is*
// lua_pushcclosure()
// lua_pushcfunction()
lua_pushlightuserdata( L, p ); // light userdata
lua_pushstring( L, "string" );
lua_pushlstring( L, "定长 string", len );
lua_pushfstring( L, "[%s] 十分受限的 sprintf", "参数1");
lua_pushvfstring( L, ...) // vprintf
lua_pushnil( L );
lua_pushthread( L ); // ???
lua_pushvalue( L ); // 对指定的栈元素拷贝
lua_pushinteger(L, 99 ); // 第一个返回值
lua_pushnumber(L, 9.9 ); // 第二个返回值
// 这个函数需要返回两个值,之前有调用 lua_pop,清空了栈,
// 如果没有清空,lua 也会丢弃不需要的栈数据,比如现在的 push,
// 但是函数只需要返回2个,除了最后两个(-1,-2)会被保留,其他的都将被丢弃
return 2;
}
int 闭包函数( lua_State *L ) {
double upval1 = 0, upval2 = 0;
/* 注意upvalue索引1,2是闭包依赖的,不会和其他的闭包中的索引冲突 */
upval1 = lua_tonumber(L, lua_upvalueindex(1) );
upval2 = lua_tonumber(L, lua_upvalueindex(2) );
upval1++; upval2++;
lua_pushnumber(L, upval1);
lua_replace(L, lua_upvalueindex(1));/* 更新upvalue1 的值 */
lua_pushnumber(L, upval2);
lua_replace(L, lua_upvalueindex(2));/* 更新upvalue2 的值 */
return 0;
}
int 闭包产生器( lua_State *L ) {
lua_pushstring( lua, "闭包的参数1" );
lua_pushstring( lua, "闭包的参数2" );
lua_pushcclosure( lua, 闭包函数, <闭包函数需要的闭包的参数> ); // 弹出所有闭包的参数
return 1;
}
lua_register( lua, "closure_name", 闭包产生器 );
// 将 fun_name 函数注册为的全局函数
lua_register( lua, "fun_name", my_fun_name );
// 导出函数,可以作为 lua 的扩展库
// 注意"模块名",要一致!!!
int luaopen_模块名(lua_State* lua) {
static struct luaL_Reg funs[] = {
{"fun_name", my_fun_name},
{NULL, NULL},
};
luaL_register( lua, "模块名", funs );
return 1;
}
// 销毁指定 Lua 状态机中的所有对象
lua_close( lua );
lua 运算符函数
lua_lessthan 小于运算符
如果索引 index1 处的值小于 索引 index2 处的值时,返回 1 ; 否则返回 0 。 其语义遵循 Lua 中的 < 操作符(就是说,有可能调用元方法)。 如果任何一个索引无效,也会返回 0 。
int lua_lessthan (lua_State *L, int index1, int index2);
lua_concat 连接符 …
连接栈顶的 n 个值, 然后将这些值出栈,并把结果放在栈顶。 如果 n 为 1 ,结果就是一个字符串放在栈上(即,函数什么都不做); 如果 n 为 0 ,结果是一个空串。 连接依照 Lua 中创建语义完成(参见 §2.5.4 )。
void lua_concat (lua_State *L, int n);
lua_equal ==
int lua_equal (lua_State *L, int index1, int index2);
其他函数
lua_load
加载 lua 代码段入栈(不执行)
int lua_load (lua_State *L,
lua_Reader reader,
void *data,
const char *chunkname);
lua_insert
将栈顶元素插入到有效索引处
禁止伪索引
void lua_insert (lua_State *L, int index);
lua_rawset
类似于 lua_settable, 但是是作一个直接赋值(不触发元方法)。
void lua_rawset (lua_State *L, int index);
lua_rawseti
等价于 t[n] = v, 这里的 t 是指给定索引 index 处的一个值, 而 v 是栈顶的值。
函数将把这个值弹出栈。 赋值操作是直接的;就是说,不会触发元方法。
void lua_rawseti (lua_State *L, int index, int n);
lua_replace
把栈顶元素移动到给定位置,不移动任何元素(因此在那个位置处的值被覆盖掉)。
扫描二维码关注公众号,回复:
10946667 查看本文章
void lua_replace (lua_State *L, int index);