toluaframework中C#怎么调用Lua的方法以及无GC方法

问题

用过luaframework框架的人应该都知道框架提供了Util的工具类,工具类提供了一个方法就是Util.CallMethod的方法,方便Unity中直接调用lua层的方法。

Util.CallMethod

        /// <summary>
        /// 执行Lua方法
        /// </summary>
        public static object[] CallMethod(string module, string func, params object[] args)
        {
   
            LuaManager luaMgr = AppFacade.Instance.GetManager<LuaManager>(ManagerName.Lua);
            if (luaMgr == null)
            {
   
                Debug.LogError("lua模块“" + module + "”未被找到");
                return null;
            }
            return luaMgr.CallFunction(module + "." + func, args);
        }

LuaManager.CallFunction

下面这里使用的框架提供的方法,但是这个方法是有GC的,我们在进入到luaMgr.CallFunction中查看一下

// Update is called once per frame
        public object[] CallFunction(string funcName, params object[] args) {
   
            LuaFunction func = lua.GetFunction(funcName);
            if (func != null) {
   
                return func.LazyCall(args);
            }
            return null;
        }

从上面的代码中我们可以看到实际上他调用的是LazyCall(),这个方法的返回值是object[],这必然是需要我们自己拆箱装箱,有GC的操作,尽可能避免拆箱装箱可以减少性能的消耗。

LuaFunction.LazyCall

这个方法作者也提示了是有GC的,这里让我们使用的是Invoke的方法调用,这样我们不需要有装箱拆箱的转换操作,这里可以直接转换成我们需要的数据。

        //慎用, 有gc alloc
        [System.Obsolete("LuaFunction.LazyCall() is obsolete.Use LuaFunction.Invoke()")]
        public object[] LazyCall(params object[] args)
        {
   
            BeginPCall();
            int count = args == null ? 0 : args.Length;

            if (!luaState.LuaCheckStack(count + 6))
            {
   
                EndPCall();
                throw new LuaException("stack overflow");
            }
            
            PushArgs(args);
            PCall();
            object[] objs = luaState.CheckObjects(oldTop);
            EndPCall();
            return objs;
        }

解决方案

这里我只举一个例子写一个两个参数的方法,多个参数的方法模仿我这个自己写就好了,需要多少参数写多少个方法即可

LuaFunction脚本

我们先看看这个脚本作者给我们提供了什么
这里作者给我们提供了无返回值的多参数Call的方法,也提供了有返回值的多参数Invoke
在这里插入图片描述

无GC消耗的调用

找到LuaManager脚本中原始有GC消耗的脚本,在他下方我们加两个多态写法
在这里插入图片描述
添加两个无GC消耗的多态方法

 	// Update is called once per frame 原始有GC的方法
    public object[] CallFunction(string funcName, params object[] args) {
   
        LuaFunction func = lua.GetFunction(funcName);
        if (func != null) {
   
            return func.LazyCall(args);//这里有GC
        }
        return null;
    }

	//有返回值并且有两个参数的无GC调用方法
    public R CallFunction<T1,T2,R>(string funcName, T1 t1,T2 t2)
    {
   
        LuaFunction func = lua.GetFunction(funcName);
        if (func != null)
        {
   
            return func.Invoke<T1,T2,R>(t1,t2);
        }
        return default;
    }

	//无返回值并且有两个参数的无GC调用方法
    public void CallFunction<T1, T2>(string funcName, T1 t1, T2 t2)
    {
   
        LuaFunction func = lua.GetFunction(funcName);
        if (func != null)
        {
   
            func.Call<T1, T2>(t1, t2);
        }
    }

打开Util工具类脚本,找到原始有GC的工具类调用方法
在这里插入图片描述
在这下方我们写两个调用方法封装一下

		/// <summary>
        /// 执行Lua方法 有GC
        /// </summary>
        public static object[] CallMethod(string module, string func, params object[] args)
        {
   
            LuaManager luaMgr = AppFacade.Instance.GetManager<LuaManager>(ManagerName.Lua);
            if (luaMgr == null)
            {
   
                Debug.LogError("lua模块“" + module + "”未被找到");
                return null;
            }
            return luaMgr.CallFunction(module + "." + func, args);
        }

		//无返回值无GC两个参数的方法
        public static void NoGCCallMethod<T1, T2>(string module, string func, T1 t1, T2 t2)
        {
   
            LuaManager luaMgr = AppFacade.Instance.GetManager<LuaManager>(ManagerName.Lua);
            if (luaMgr == null)
            {
   
                Debug.LogError("lua模块“" + module + "”未被找到");
            }
            luaMgr.CallFunction(module + "." + func, t1 ,t2);
        }

		//有返回值无GC两个参数的方法
        public static R InvokeMethod<T1, T2, R>(string module, string func, T1 t1, T2 t2)
        {
   
            LuaManager luaMgr = AppFacade.Instance.GetManager<LuaManager>(ManagerName.Lua);
            if (luaMgr == null)
            {
   
                Debug.LogError("lua模块“" + module + "”未被找到");
                return default;
            }
            return luaMgr.CallFunction<T1, T2, R>(module + "." + func, t1, t2);
        }

用法总结

下面是原始有GC的调用方法和无GC的调用方法,调用参考
在这里插入图片描述

相关推荐

  1. Lua调用函数方式汇总

    2023-12-28 00:26:02       30 阅读
  2. Go使用反射动态方法调用

    2023-12-28 00:26:02       52 阅读
  3. C#调用非托管dll,并从dll调用C#方法

    2023-12-28 00:26:02       27 阅读
  4. C#方法

    2023-12-28 00:26:02       27 阅读
  5. Rust链式调用方法

    2023-12-28 00:26:02       110 阅读
  6. C# 方法递归调用

    2023-12-28 00:26:02       62 阅读
  7. Lua 如何在Lua调用C/C++函数

    2023-12-28 00:26:02       38 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-28 00:26:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-28 00:26:02       100 阅读
  3. 在Django里面运行非项目文件

    2023-12-28 00:26:02       82 阅读
  4. Python语言-面向对象

    2023-12-28 00:26:02       91 阅读

热门阅读

  1. C语言第五十七弹---模拟使用memmove函数

    2023-12-28 00:26:02       60 阅读
  2. 【uniapp】Uniapp cli 自动化打包脚本实现

    2023-12-28 00:26:02       66 阅读
  3. uniapp常见的标签

    2023-12-28 00:26:02       64 阅读
  4. 1.Linux是什么与如何学习

    2023-12-28 00:26:02       66 阅读
  5. Kotlin 数据类

    2023-12-28 00:26:02       56 阅读
  6. JVM钩子

    2023-12-28 00:26:02       55 阅读
  7. 什么是 MVVM?

    2023-12-28 00:26:02       56 阅读
  8. 深度学习中的收敛是什么意思?

    2023-12-28 00:26:02       51 阅读
  9. Linux - 记录问题:Ubuntu查看文件夹大小

    2023-12-28 00:26:02       59 阅读
  10. android 四大组件和handler、looper

    2023-12-28 00:26:02       49 阅读