基础:

  • lua与C语言使用“栈”交互数据,“栈”是一种先进后出的机制,“压栈”就是将一个元素放到栈顶,lua_push* 函数就是将不同类型压入到栈中。
  • 圧栈的第一个元素编号为1,第二个元素编号为2,以此类推到N,当然也可以使用负数表示,-1表示栈顶(最上面的元素,也是倒数第一个元素),-2表示倒数第二个元素,以此类推到-N。
  • lua调用c函数时(如上例的mylua.add(20, 30)),栈的功能如下:

      1. 传递的参数依次圧栈,如上例,第一个参数20的编号为1(也叫-2),第二个参数30的编号为2(也叫-1),lua_is* 函数用于判断数据类型,lua_check*函数用于检测并返回数据,lua_to*用于转换数据为制定的类型,当然lua_type用于返回数据的类型。

       2. 函数的返回值为栈顶,可以使用lua_push*制定返回的数据值,如果需要返回table类型,需要使用lua_newtable和lua_settable.


以下是一些常见函数的使用方法:

1. lua_gettop :返回栈的层级

2. 需要返回数字类型是,使用lua_pushnumber,需要返回字符串时使用lua_pushstring或者lua_pushlstring, 需啊哟返回table时使用lua_newtable。

3,lua_pushlstring与lua_pushstring的区别:前者可以获取字符串的长度,后者不能,后者其实是前者的简化版。

4. 读取table结果的方法如下:需要首先圧栈key,然后使用lua_gettable或者lua_rawget获取字段值

//假设t的栈编号为-1,如果希望获取t['name'] 的值
char * key = "name";
lua_pushstring(L, key);  //将字段name圧栈,变成栈顶 ,此刻t变为-2
lua_gettable(L, -2); //获取字段name的值,并替换栈顶的值
//上面两句等价于使用lua_getfield(L, -2,  key),使用更简单
//假设t的栈编号为-1,如果希望获取t[1] 的值
lua_pushnumber(L, 1);  //将字段1圧栈,变成栈顶 ,此刻t变为-2
lua_gettable(L, -2); //获取字段1的值,并替换栈顶的值
//上面两句等价于使用lua_getrawi(L, -2, 1),使用更简单
//这里可以获取栈顶的值,然后进行逻辑错误,如 char s[] = lua_tostring(L, -1);
5. 返回table结果的方法如下:需要首先圧栈key,然后圧栈value,最后使用lua_settable或者lua_rawset设置字段值

//假设t的栈编号为-1,如果希望设置['age']  = 11
char * key = "age";
lua_newtable(L);//创建table,并圧栈
lua_pushstring(L, key);  //将字段name圧栈,变成栈顶 ,此刻t变为-2
lua_pushinteger(L, 11);//将字段name圧栈,变成栈顶 ,此刻t变为-3
lua_settable(L, -3); //将栈顶作为key,-2个元素作为value,圧栈到栈顶,并弹出key和value
//上面三句等价于使用lua_pushinteger(L,11) 和 lua_setfield(L, -2,  key),使用更简单
 

6. lua_gettable和lua_rawget的区别为:后者不会读取元表,所有性能更好。
7. lua_concat可以连接多层栈的值,并圧栈到栈顶。
8.可以使用luaL_Buffer,提高大量字符串拼接的性能,步骤为:
     luaL_Buffer b; //定义
      const char *s = “abcd”;
      luaL_buffinit(L, &b); //初始化变量
      for (i=0; i<l; i++) {
         luaL_addchar(&b, toupper(s[i]) ); //拼接字符串
      
      }
      luaL_pushresult(&b); //将结果圧栈到栈顶