LUA 与 C
栈
- 使用栈进行lua和C数据交换
- 要将一个值传给lua,需要先将该值压入栈,然后调用lua api函数,lua会从栈中获取该值并从栈中弹出
入栈API
1
2
3
4
5
6void lua_pushnil(lua_State *);
void lua_pushboolean(lua_State *, int bool);
void lua_pushstring(lua_State *, const char *s);
void lua_pushlstring(lua_State *, const char *s, size_t len);
void lua_pushnumber(lua_State *, lua_Number n);// 双精度浮点
void lua_pushinteger(lua_State *, lua_Integer n);// 整型,足以存储大型字符串长度,定义为ptrdiff_t类型栈大小:默认20(LUA_MINSTACK定义),通过如下代码检查栈大小
1
int lua_checkstack(lua_State *, int sz)
查询
通过索引查找栈中元素:1栈底,2次栈底,-1表示栈顶,-2次栈顶
1
lua_tostring(L, -1);// 将栈顶元素弹出转换为string
检查栈元素类型
1
2int lua_isstring(lua_State *L, int index);
int lua_isnumber(lua_State *L, int index);栈元素转换
1
int lua_toboolean(lua_State *L, int index);
不要在C函数之外调用在C函数内获取的指向字符串的指针(函数退出清理栈)
C操作栈函数列表
1 | int lua_getglobal(L, const char *name);//全局变量name值压栈,并返回该值类型 |
C调用lua函数
- 待调用函数入栈,并压入参数,然后使用pcall调用,最后将结果从栈中弹出。
1
2
3function (x, y)
reutrn x + y
end
- 调用代码示例(前提需要打开库,并运行了以上lua代码):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17int callluaFunc(int x, int y)
{
int ret = 0;
lua_getglobal(L, "luaf");
lua_pushnumber(L, x);
lua_pushnumber(L, y);
// 执行调用,2个参数1个结果
if (lua_pcall(L, 2, 1, 0))
error(L, "error running function:%s", lua_tostring(L, -1));
// 检查结果
if (!lua_isnumber(L, -1))
error(L, "result need to be number");
ret = lua_tonumber(L, -1));
lua_pop(L, 1);
return ret;
}
LUA调用C
typedef int (lua_CFunction)(lua_State L);// 返回压入栈中结果数量,方便与栈中其余值区分
调用前需要提前注册c函数
1
void lua_pushfunction(L, lua_CFuntion);
示例:
1
2lua_pushfunction(L, c_function);// 压入函数
lua_setglobal(L, "cfunctionname");//出栈,将函数赋予全局变量cfuntionname中require “myclib” 过程:链接动态库到lua,并寻找luaopen_myclib函数,将其注册为一个lua函数,然后调用它以打开模块
userdata
- lua_newuserdata
1
2void lua_newuserdata(lua_State *L, size_t sz);
这个函数分配一块指定大小的内存块, 把内存块地址作为一个完全用户数据压栈, 并返回这个地址。 宿主程序可以随意使用这块内存