Lua CAPI函数说明

学习时出现的疑问
1.luaL_loadstring()入栈了什么东西
答:入栈了一个module,可以被pcall调用

2.为什么循环100次入栈,程序就崩了,是不是因为栈满了
3.为什么调用lua_close的时候程序会崩

4.入栈了userdata后,lua端怎么使用
答:参考 函数说明lua_newuserdata

5.pcall的返回值
答:0表示正常,非零则为异常,同时会将错误提示入栈

注意事项:

1.lua的栈中会有2种索引,一个是1为栈底,往上递增;一个是-1为栈顶,往下递减
2.如果API返回了一个int,则他需要为0才表示没有异常,其他结果都是异常
3.在使用lua_to…时,既可以用负索引,也可以用正索引
4.set表示出栈,get表示入栈
5.如果需要传递C对象,则这个对象要为userdata类型,使用lua_newuserdata创建
6.C#创建一个userdata的方法

Person person = new Person();	//自定义对象Person
GCHandle handle = GCHandle.Alloc(person);	//分配内存
IntPtr obj = GCHandle.ToIntPtr(handle);	//handle转成指针
IntPtr userdata = LuaAPI.lua_newuserdata(L, IntPtr.size);	//创建userdata
Marshal.WriteIntPtr(userdata, obj);	//把对象写入userdata中

7.C#获取userdata的方法

IntPtr p = LuaAPI.lua_topointer(L, -2);	//userdata的位置
IntPtr dataPtr = Marshal.ReadIntPtr(p);	//获取到对象指针
GCHandle handle = GCHandle.FromIntPtr(dataPtr);	//转为C# GCHandle
object obj = handle.Target;	//Target就是对象
Person person = (obj as Person);

8.函数的返回值
入栈则表示lua返回值
C# return 0 表示函数有问题,不会返回任何数据。即使已经入栈了数据,也会被清掉。注意与pcall中的返回值相反,pcall返回0表示正常
return 1则表示函数执行正常,栈中的数据可以正常到lua端
如下:

private static int TestCClose(lua_State L)
{
	Console.WriteLine("C# 函数调用!");
	MyLib.lua_pushinteger(L, 7777);
	//return 0 返回0,函数异常,入栈的数据不会回到lua端中
	return 1;	//返回1,结果正常
}

函数说明

[-(nargs + 1), +(nresults|1), -]
int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc);
出栈nargs+1,就是说如果没有参数时,他也会把当前栈顶出栈,如果栈顶不是函数则报错

[-(nargs + 1), +(nresults|1), -]
int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc);
与lua中的调用函数调用一样,这里他会去调用栈顶。
如果栈顶是函数,则正常调用;如果不是函数,则调用报错。所以一般来说栈初始化完了后,栈中应该只剩下一开始加载的那个module

[-0, +1, m]
void *lua_newuserdata (lua_State *L, size_t size);
创建一个userdata,这个对象在创建后,不可以使用setfield等操作访问k,v,因为userdata没有这种操作,会让程序直接崩掉。
正确操作:1.创建一个元表meta,将k,v全都设置到元表上;2.把userdata的元表设置为meta

[-0, +1, m]
int luaL_newmetatable (lua_State *L, const char *tname)
创建元表到栈顶

[-1, +0, m]
int luaL_ref (lua_State *L, int t);
将栈顶数据转为引用并且出栈。一般操作是将一个函数注册到注册表中,方便其他地方获取这个函数。调用时会在注册表里生成一个key,并且把数据赋值到key里,同时返回这个key。使用rawgeti则可以将注册表的对应key值的数据入栈
比如:

//返回的funcRef其实是注册表的索引,如果想要获取这个函数
//则 LuaAPI.lua_rawgeti(L, LuaAPI.LUA_REGISTRYINDEX, funcRef);
//rawgeti后会把函数放到栈顶
int funcRef = LuaAPI.luaL_ref(L, LuaAPI.LUA_REGISTRYINDEX);

这种方法可以将函数注册到C#委托或者事件中

[-0, +0, –]
void lua_close (lua_State *L);
销毁L创建的所有对象,并且释放L使用的所有动态内存。
如果没有及时销毁,会造成内存泄漏

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值