XLUA学习--C#访问Lua全局函数

本文详细介绍了如何使用C#调用Lua中的各种函数,包括无参数、带参数、有返回值及多个返回值的情况,并探讨了[CSharpCallLua]的作用及LuaEnv.Dispose()的注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上一篇讲到了通过接口的形式,可以访问表内部的函数,那如果这个方法是一个全局的函数,就是这篇博客要讲解的。

先上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<T>方法来实现。Lua中对应的函数,可以通过C#种的事件Action和委托delegate来实现。

1.无参数的调用

LuaEnv env = new LuaEnv();
env.DoString("require 'CSharpCallLua' ");
Action ac1=env.Global.Get<Action>("TestOne");
ac1();

2.带参数的调用

接下来的几种,都需要在方法前加上   [CSharpCallLua],如果不加的话,会报如下错误。

稍后再分析[CSharpCallLua]这句话到底起什么样的一个作用。

这里不能再用Action去接收。而需要去委托,具体什么原因还真不敢下结论。个人感觉[CSharpCallLua]定义的,是一个类型。比如上一篇博客说到的接口类,和现在用委托自定义的一种类型。先上错误的写法。

    [CSharpCallLua]
    private Action<int, int> ac1;
    ac1 = env.Global.Get<Action<int, int>>("TestTwo");

再上正确的写法

    [CSharpCallLua]
    delegate void AC2(int a,int b);
    AC2 ac2 = env.Global.Get<AC2>("TestTwo");
    ac2(2,5);


3.带返回值的调用

和上面委托就没啥区别了,也是上一个正确写法和错误写法

错误写法

[CSharpCallLua]
private Func<int, int, int> ac3;

int res=ac3(2,5);

这里Func的用法如果不会就去自行解决好了。

正确写法

    [CSharpCallLua]
    delegate int AC3(int a, int b);
    AC3 ac3= env.Global.Get<AC3>("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<AC4>("TestFour");
    int res1;
    int res2;
    ac4(2,3,out res1,out re2);

当然这里也可以用ref来实现,就不说了。

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

接下来写两个过程中发现的需要注意的问题

1.在调用LuaEnv.Dispose()之前,要把所有访问过程中生成的函数置为空,否则会报无法释放的错误。

需要加入ac1=null之后再去释放。

2.就是  [CSharpCallLua]这个到底起的什么作用了,在我研究过程中发现,比如上述2带参数的调用。

我直接通过错误写法,下面简称T1
Action<int, int> ac1 = env.Global.Get<Action<int, int>>("TestTwo");

是不行的,但是!!!如果我上面写了正确方法:简称T2

    [CSharpCallLua]
    delegate void AC2(int a,int b);

而我并不去通过AC2去生成新的方法实例,只是把它写那儿,然后再通过T1写法去写代码,竟然是可以走通的。

刚开始怀疑是在在类初始化时做的手脚。我把T1放在了Awake里,还是可以走通的。个人感觉,问题出在委托delegate 本身和Action之间的关系。Action和Func,本来就属于U3D对delegate委托的一种封装,所以当本身将T2前加了[CSharpCallLua]的时候,它就等同于给Action<int,int>类型的方法加上了[CSharpCallLua]。好吧,我也只能说个人猜测了,原理到底是啥,我不敢下结论,如果有大神看到这里,也可以帮我分析解决下,个人觉得后者可能性非常大。

这块儿为什么对于带参数的委托需要自定义,而不能用Action和Func暂时还不太清楚。也希望看到的朋友能帮忙解释一下。

5.通过Luafunction调用方法

它的参数,以及返回值都是object[]类型的,可以传递很多个。但和上面委托的方式相比,缺点就在于运行消耗较大,有点在于不需要像上面那样自己定义。不过貌似XLUA不建议我们用这个。

  LuaFunction lf = env.Global.Get<LuaFunction>("compare1");
        lf.Call();

引用文档里的话,如果lua的实现的部分都以delegate和interface的方式提供,使用方可以完全和xLua解耦:由一个专门的模块负责xlua的初始化以及delegate、interface的映射,然后把这些delegate和interface设置到要用到它们的地方。也就是表,建议用映射,方法,建议用delegate.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值