上一篇讲到了通过接口的形式,可以访问表内部的函数,那如果这个方法是一个全局的函数,就是这篇博客要讲解的。
先上Lua中的代码。
function TestOne()
print('no parm')
end
function TestTwo(a,b)
print(a,b)
end
function TestThree(a,b)
return a+b
end
function TestFour(a,b)
return a+b,a,b
end
上面有四个函数,分别为没有参数,带参数,有返回值,有多个返回值这4种情况。
还是用LuaEnv.Global.Get
1.无参数的调用
LuaEnv env = new LuaEnv();
env.DoString("require 'CSharpCallLua' ");
Action ac1=env.Global.Get("TestOne");
ac1();
2.带参数的调用
接下来的几种,都需要在方法前加上 [CSharpCallLua],如果不加的话,会报如下错误。
稍后再分析[CSharpCallLua]这句话到底起什么样的一个作用。
这里不能再用Action去接收。而需要去委托,具体什么原因还真不敢下结论。个人感觉[CSharpCallLua]定义的,是一个类型。比如上一篇博客说到的接口类,和现在用委托自定义的一种类型。先上错误的写法。
[CSharpCallLua]
private Action ac1;
ac1 = env.Global.Get>("TestTwo");
再上正确的写法
[CSharpCallLua]
delegate void AC2(int a,int b);
AC2 ac2 = env.Global.Get("TestTwo");
ac2(2,5);
3.带返回值的调用
和上面委托就没啥区别了,也是上一个正确写法和错误写法
错误写法
[CSharpCallLua]
private Func ac3;
int res=ac3(2,5);
这里Func的用法如果不会就去自行解决好了。
正确写法
[CSharpCallLua]
delegate int AC3(int a, int b);
AC3 ac3= env.Global.Get("compare");
int v = ac3(2, 3);
4.带多个返回值的调用
Lua中支持多个返回值的回调,但C#没这么一说。这时候就可以在上面带一个返回值的写法基础上通过ref,out形式获取别的返回值。
[CSharpCallLua]
delegate int AC4(int a, int b,out int c,out int d);
AC4 ac4=env.Global.Get("TestFour");
int res1;
int res2;
ac4(2,3,out res1,out re2);
当然这里也可以用ref来实现,就不说了。
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
接下来写两个过程中发现的需要注意的问题
1.在调用LuaEnv.Dispose()之前,要把所有访问过程中生成的函数置为空,否则会报无法释放的错误。
需要加入ac1=null之后再去释放。
2.就是 [CSharpCallLua]这个到底起的什么作用了,在我研究过程中发现,比如上述2带参数的调用。
我直接通过错误写法,下面简称T1
Action
是不行的,但是!!!如果我上面写了正确方法:简称T2
[CSharpCallLua]
delegate void AC2(int a,int b);
而我并不去通过AC2去生成新的方法实例,只是把它写那儿,然后再通过T1写法去写代码,竟然是可以走通的。
刚开始怀疑是在在类初始化时做的手脚。我把T1放在了Awake里,还是可以走通的。个人感觉,问题出在委托delegate 本身和Action之间的关系。Action和Func,本来就属于U3D对delegate委托的一种封装,所以当本身将T2前加了[CSharpCallLua]的时候,它就等同于给Action
这块儿为什么对于带参数的委托需要自定义,而不能用Action和Func暂时还不太清楚。也希望看到的朋友能帮忙解释一下。
5.通过Luafunction调用方法
它的参数,以及返回值都是object[]类型的,可以传递很多个。但和上面委托的方式相比,缺点就在于运行消耗较大,有点在于不需要像上面那样自己定义。不过貌似XLUA不建议我们用这个。
LuaFunction lf = env.Global.Get("compare1");
lf.Call();
引用文档里的话,如果lua的实现的部分都以delegate和interface的方式提供,使用方可以完全和xLua解耦:由一个专门的模块负责xlua的初始化以及delegate、interface的映射,然后把这些delegate和interface设置到要用到它们的地方。也就是表,建议用映射,方法,建议用delegate.