【Lua与C#交互②】加载Lua文件
今天继续学习Lua和C#的交互,今天要讲的是加载Lua文件。 之后的例子都会使用tolua来写,因为tolua提供的lua原生api比xlua更多。当然你也可以自己编译lua的dll放到unity里面。<hr/>
加载文件使用的是luaL_loadfile这个api,案例如下: 结果是先打印100,再打印200
var L = LuaDLL.luaL_newstate();
var path = Application.dataPath + &#34;/Examples/02_LoadFile/02.lua&#34;;
var errorPath = Application.dataPath + &#34;/02.lua&#34;;
//返回结果不是0代表加载失败
var result = LuaDLL.luaL_loadfile(L, path);
//Debug.Log(result);
if ( result!= 0)
{
Debug.LogError(LuaDLL.lua_tostring(L, -1));
}
if(LuaDLL.lua_pcall(L, 0, 0, 0) != 0)
{
Debug.LogError(LuaDLL.lua_tostring(L, -1));
}
LuaDLL.lua_getglobal(L,&#34;a&#34;);
LuaDLL.lua_getglobal(L,&#34;b&#34;);
if (LuaDLL.lua_isnumber(L, -2) == 1)
{
Debug.Log(LuaDLL.lua_tonumber(L,-2));
}
if (LuaDLL.lua_isnumber(L, -1) == 1)
{
Debug.Log(LuaDLL.lua_tonumber(L,-1));
}
LuaDLL.lua_close(L);
Lua代码如下:
a = 100
b = 200Lua里面暂时不写函数,关于函数的调用会在之后讲。
<hr/>
接下来解释代码:
var result = LuaDLL.luaL_loadfile(L, path);
//Debug.Log(result);
if ( result!= 0)
{
Debug.LogError(LuaDLL.lua_tostring(L, -1));
}
luaL_loadfile(IntPtr luaState, string filepath)
第一个参数传入luaState,关于luaState,第一篇文章讲了。第二个参数入文件路径。返回值是数字,如果返回0代表成功,0以外的代表失败。 如果路径是正确的,没有什么好说的。如果是失败,lua是不会自己报错的。
出错时,lua会把错误信息压入栈中,所以需要调用LuaDLL.lua_tostring(L, -1) 把错误信息拿出来。 当传入错误路径时,错误信息如下:
<hr/>
if(LuaDLL.lua_pcall(L, 0, 0, 0) != 0)
{
Debug.LogError(LuaDLL.lua_tostring(L, -1));
}
lua_pcall(IntPtr luaState, int nArgs, int nResults, int errfunc)
这个函数的作用是运行之前加载的lua文件,使用loadfile后lua虚拟机并不会运行代码,只会编译代码,所以需要调用pcall。 lua_pcall包含了四个参数,分别是luaState,参数个数,返回值个数,错误处理函数在栈中的索引。本篇案例是最简单的情况,因为Lua代码没有方法,也就没有参数个数,没有返回值,我们也不处理错误。所以后面三个参数都是0。关于这个方法的复杂情况,以后会讲。
另外,luaL_loadfile和lua_pcall两步可以直接用luaL_dofile替代。
<hr/>
LuaDLL.lua_getglobal(L,&#34;a&#34;);
LuaDLL.lua_getglobal(L,&#34;b&#34;);
关于lua的栈
lua的栈是用来处理lua和其它语言交互的部分,并不是lua内部跑的代码都在这个栈上。lua内部有自己的内存区用来管理lua自身的代码。所以即使执行了lua文件,lua文件里面的公共变量也不是在栈上。
lua_getglobal(IntPtr luaState, string name)
lua_getglobal把lua里的公共变量压栈,以便C#端能够调用。上面两行代码的意思是把&#34;a&#34;和&#34;b&#34;分别压栈。
<hr/>
if (LuaDLL.lua_isnumber(L, -2) == 1)
{
Debug.Log(LuaDLL.lua_tonumber(L,-2));
}
if (LuaDLL.lua_isnumber(L, -1) == 1)
{
Debug.Log(LuaDLL.lua_tonumber(L,-1));
}
lua_isnumber(IntPtr luaState, int idx)
最后打印结果,lua_isnumber上篇也讲了,不过上篇文章用的是xlua,xlua封装lua原生api的时候把返回值改成bool了,实际上lua原生api是返回int值。返回1代表true,返回0代表false。 注意,当调用lua_tonumber时并不会把返回的值出栈。如果想把栈顶出栈,需要调用LuaDLL.lua_pop(L,1)。可以尝试下面的代码: 结果是先打印最后入栈的b的值200,再打印a的值100
if (LuaDLL.lua_isnumber(L, -1) == 1)
{
Debug.Log(LuaDLL.lua_tonumber(L,-1));
}
LuaDLL.lua_pop(L,1);
if (LuaDLL.lua_isnumber(L, -1) == 1)
{
Debug.Log(LuaDLL.lua_tonumber(L,-1));
}
那么这次的内容就这些了, github工程地址对应的是Example/02_LoadFile文件夹。
系列文章:
【Lua与C#交互①】Lua中的栈_lua_水鸡的游戏开发学习笔记-CSDN博客
【Lua与C#交互②】加载Lua文件_lua_水鸡的游戏开发学习笔记-CSDN博客
【Lua与C#交互③】方法调用和错误处理函数_水鸡的游戏开发学习笔记-CSDN博客
qq群:891809847 写的很详细,感谢分享。
页:
[1]