前言#
前两章我们总结了lua_is*系列和lua_to*系列,掌握了lua栈内值的判断和转换方法,现在我们来看看lua_push*系列,这些api的作用是将相应类型的值压入栈内,说实话这一组api有好多我也没有使用过,但是为了知识的完整性,在这里只是简单的列举在这里,然后一起学习一下。
内容#
lua_pushboolean##
- 原型:void lua_pushboolean (lua_State *L, int b);
- 解释:把 b 作为一个 boolean 值压入堆栈。
lua_pushcclosure##
- 原型:void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
- 解释:把一个新的 C closure 压入堆栈。
lua_pushcfunction##
- 原型:void lua_pushcfunction (lua_State *L, lua_CFunction f);
- 解释:将一个 C 函数压入堆栈。 这个函数接收一个 C 函数指针,并将一个类型为 function 的 Lua 值 压入堆栈。当这个栈顶的值被调用时,将触发对应的 C 函数。
lua_pushfstring##
- 原型:const char *lua_pushfstring (lua_State *L, const char *fmt, ...);
- 解释:把一个格式化过的字符串压入堆栈,然后返回这个字符串的指针。 它和 C 函数 sprintf 比较像,不过有一点区别如下:
- 你需要为结果分配空间: 其结果是一个 Lua 字符串,由 Lua 来关心其内存分配 (同时通过垃圾收集来释放内存)。
- 这个格式化转换非常的受限。 不支持 flag 、宽度、或是指定精度。 它只支持下面这些: '%%' (插入一个 '%'), '%s' (插入一个带零终止符的字符串,没有长度限制), '%f' (插入一个 lua_Number), '%p' (插入一个指针或是一个十六进制数), '%d' (插入一个 int), '%c' (把一个 int 作为一个字符插入)。
lua_pushinteger##
- 原型:void lua_pushinteger (lua_State *L, lua_Integer n);
- 解释:把 n 作为一个数字压栈。
lua_pushlightuserdata##
- 原型:void lua_pushlightuserdata (lua_State *L, void *p);
- 解释:把一个 light userdata 压栈。 userdata 在 Lua 中表示一个 C 值。light userdata 表示一个指针。它是一个像数字一样的值:你不需要专门创建它,它也没有独立的 metatable ,而且也不会被收集(因为从来不需要创建)。只要表示的 C 地址相同,两个 light userdata 就相等。
lua_pushlstring##
- 原型:void lua_pushlstring (lua_State *L, const char *s, size_t len);
- 解释:把指针 s 指向的长度为 len 的字符串压栈。Lua 对这个字符串做一次内存拷贝(或是复用一个拷贝),因此 s 处的内存在函数返回后,可以释放掉或是重用于其它用途,字符串内可以保存有零字符。
lua_pushnil##
- 原型:void lua_pushnil (lua_State *L);
- 解释:把一个 nil 压栈。
lua_pushnumber##
- 原型:void lua_pushnumber (lua_State *L, lua_Number n);
- 解释:把一个数字 n 压栈。
lua_pushstring##
- 原型:void lua_pushstring (lua_State *L, const char *s);
- 解释:把指针 s 指向的以零结尾的字符串压栈。Lua 对这个字符串做一次内存拷贝(或是复用一个拷贝),因此 s 处的内存在函数返回后,可以释放掉或是重用于其它用途。字符串中不能包含有零字符,第一个碰到的零字符会认为是字符串的结束。
lua_pushthread##
- 原型:int lua_pushthread (lua_State *L);
- 解释:把 L 中提供的线程压栈。 如果这个线程是当前状态机的主线程的话返回 1 。
lua_pushvalue##
- 原型:void lua_pushvalue (lua_State *L, int index);
- 解释:把堆栈上给定有效处索引处的元素作一个拷贝压栈。
lua_pushvfstring##
- 原型:const char *lua_pushvfstring (lua_State *L, const char *fmt, va_list argp);
- 解释:等价于 lua_pushfstring, 不过是用 va_list 接收参数,而不是用可变数量的实际参数。
Usage##
- 首先我们来新建一个文件,将文件命名为pushtest.lua然后编写如下代码:
-- 定义一个table
information =
{
name = "tom",
age = 28,
sex = "man",
married = true;
}
function func_print_data()
print("lua -- > information.name = "..information.name)
print("lua -- > information.age = "..information.age)
print("lua -- > information.sex = "..information.sex)
if information.married then
print("lua -- > "..information.name.." is married")
else
print("lua -- > "..information.name.." is not married")
end
end
- 接下来们来编写c++调用代码:
lua_State *L = lua_open();
luaL_openlibs(L);
luaL_dofile(L,"pushtest.lua"); // 加载执行lua文件
lua_getglobal(L,"information"); // 将全局表压入栈
lua_pushstring(L, "name"); // 将要修改的变量名压入栈
lua_pushstring(L, "AlbertS"); // -->lua_pushstring用法
lua_rawset(L, -3);
lua_pushstring(L, "age");
lua_pushinteger(L, 20); // -->lua_pushinteger用法
lua_rawset(L, -3);
lua_pushstring(L, "married");
lua_pushboolean(L, false); // -->lua_pushboolean用法
lua_rawset(L, -3);
lua_getglobal(L, "func_print_data"); // 函数入栈
lua_pcall(L, 0, 0, 0); // 打印信息
lua_close(L); // 关闭lua环境
- 结果
总结#
- 这一章的代码中api的使用较少,原因是有一些api我也没用过,在这里只起到抛砖引玉的作用,希望大家可以掌握api使用的思路。
- lua_pushcfunction 是作为一个宏定义出现的,只是 lua_pushcclosure(L,f,0) 的简便写法。
- lua api总结到现在已经有十章了,相信日常工作中所涉及的大部分、高频率使用的api都已经在这十章之中讲过了,其实这就是一个相互学习的过程,我总结了一遍也从中发现了一些之前没有遇到过的问题,也给大家找到了学习的例子。
- 另外大家熟悉了这些api以后可以练习一下,每一章我都给出了代码和运行结果,大家可以试试读代码,写结果,看看结果是不是和自己想的一样。
- 好了,lua api系列暂时就写到这里,今后有需要我会继续补充,如果有什么地方写的不正确,欢迎大家批评指正。