找回密码
 立即注册
查看: 343|回复: 0

腾讯XLua 03-CSharp Invoke Lua

[复制链接]
发表于 2021-8-13 10:42 | 显示全部楼层 |阅读模式
using UnityEngine; using System.Collections; using XLua;  publicclass MyInvokeLua : MonoBehaviour { //创建一个接口 用于生成 调用函数     [CSharpCallLua]      //这是一个生成调用函数用的标签 生成CSharp调用Lua,加这标签publicinterface ICalc {         int Add(int a, int b);         int Mult { get; set; }     }      [CSharpCallLua]     //(1)在方法声明中的 params 关键字之后不允许任何其他参数,并且在方法声明中只允许一个 params 关键字。//(2)该参数必须标识一个一维数组,但类型不限,对该参数传递null或者0个数目的数组的引用都是合法的*publicdelegate ICalc CalcNew(int mult, paramsstring[] arg);                 //创建一个元表privatestring script = @"                 local cal_mt = {                     __index = {                         Add = function(self, a, b)                             return (a + b) * self.Mult                         end                       }                  }                  //设置创建函数                   Calc = {                       New = function(mult, ...)                             print(...)                             return setmetatable({Mult = mult}, calc_mt)                       end                     }                 ";      void Start() {         LuaEnv luaenv = new LuaEnv();         luaenv.DoString(script);         //获得Calc.New方法 转换为CalcNew委托         CalcNew calc_new = luaenv.Global.GetInPath<CalcNew>("Calc.New");         //执行委托 获得函数 返回接口的引用         ICalc calc = calc_new(10, "hi", "john");         Debug.Log("sum(*10) = " + calc.Add(1, 2));         //修改Mult在内存中的值         calc.Mult = 100;         Debug.Log("sum(*100) = " + calc.Add(1, 2));         luaenv.Dispose();     } }点击工具栏上的 XLua/Generate Code 就会注册函数
//截取部分重要代码 namespace CSObjectWrap {          publicintAdd(int a, int b)         { #if THREAD_SAFT || HOTFIX_ENABLElock (luaEnv.luaEnvLock)             { #endif                 RealStatePtr L = luaEnv.L;                 int err_func = LuaAPI.load_error_func(L, luaEnv.errorFuncRef);                 LuaAPI.lua_getref(L, luaReference);                 //向栈中压入 "Add"                 LuaAPI.xlua_pushasciistring(L, "Add");                 //安全判断,当栈第二位置为Table时,再往下执行if (0 != LuaAPI.xlua_pgettable(L, -2))                 {                     luaEnv.ThrowExceptionFromError(err_func - 1);                 }                 //CSharp压入"Add",Lua会将叫Add的元素放入栈顶,判断得到的是否是functionif(!LuaAPI.lua_isfunction(L, -1))                 {                     LuaAPI.xlua_pushasciistring(L, "no such function Add");                     luaEnv.ThrowExceptionFromError(err_func - 1);                 }                 //将table表 压入栈顶                 LuaAPI.lua_pushvalue(L, -2);                 //删除-3位置的元素                 LuaAPI.lua_remove(L, -3);                 //压入第一个元素                 LuaAPI.xlua_pushinteger(L, a);                 //压入第二个元素                 LuaAPI.xlua_pushinteger(L, b);                 //现在在栈中的位置如下//Add (-4)->table(-3)->a(-2)->b(-1)//调用方法(L,参数个数,返回值个数,错误方法)int __gen_error = LuaAPI.lua_pcall(L, 3, 1, err_func);                 if (__gen_error != 0)                     luaEnv.ThrowExceptionFromError(err_func - 1);                   int __gen_ret = LuaAPI.xlua_tointeger(L, err_func + 1);                 LuaAPI.lua_settop(L, err_func - 1);                 return  __gen_ret; #if THREAD_SAFT || HOTFIX_ENABLE             } #endif         }            publicint Mult          {              get              { #if THREAD_SAFT || HOTFIX_ENABLElock (luaEnv.luaEnvLock)                 { #endif                     RealStatePtr L = luaEnv.L;                     int oldTop = LuaAPI.lua_gettop(L);                      LuaAPI.lua_getref(L, luaReference);                     LuaAPI.xlua_pushasciistring(L, "Mult");                     if (0 != LuaAPI.xlua_pgettable(L, -2))                     {                         luaEnv.ThrowExceptionFromError(oldTop);                     }                     //从栈顶获得int类型参数int __gen_ret = LuaAPI.xlua_tointeger(L, -1);                     LuaAPI.lua_pop(L, 2);                     return __gen_ret; #if THREAD_SAFT || HOTFIX_ENABLE                 } #endif             }               set             { #if THREAD_SAFT || HOTFIX_ENABLElock (luaEnv.luaEnvLock)                 { #endif                     RealStatePtr L = luaEnv.L;                     int oldTop = LuaAPI.lua_gettop(L);                     //C#交互 同理 同上                     LuaAPI.lua_getref(L, luaReference);                     LuaAPI.xlua_pushasciistring(L, "Mult");                     LuaAPI.xlua_pushinteger(L, value);                     if (0 != LuaAPI.xlua_psettable(L, -3))                     {                         luaEnv.ThrowExceptionFromError(oldTop);                     }                     LuaAPI.lua_pop(L, 1); #if THREAD_SAFT || HOTFIX_ENABLE                 } #endif             }          }        } }  //声明的绑定委托也会生成对应的代码public MyInvokeLua.ICalc MyInvokeLuaICalc(int mult, string[] arg)         { #if THREAD_SAFT || HOTFIX_ENABLElock (luaEnv.luaEnvLock)             { #endif                 RealStatePtr L = luaEnv.L;                 int err_func =LuaAPI.load_error_func(L, errorFuncRef);                 ObjectTranslator translator = luaEnv.translator;                  LuaAPI.lua_getref(L, luaReference);                  LuaAPI.xlua_pushinteger(L, mult);                 for (int __gen_i = 0; __gen_i < arg.Length; ++__gen_i) LuaAPI.lua_pushstring(L, arg[__gen_i]);                  int __gen_error = LuaAPI.lua_pcall(L, 1 + arg.Length, 1, err_func);                 if (__gen_error != 0)                     luaEnv.ThrowExceptionFromError(err_func - 1);                   MyInvokeLua.ICalc __gen_ret = (MyInvokeLua.ICalc)translator.GetObject(L, err_func + 1, typeof(MyInvokeLua.ICalc));                 LuaAPI.lua_settop(L, err_func - 1);                 return  __gen_ret; #if THREAD_SAFT || HOTFIX_ENABLE             } #endif         }
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-24 10:00 , Processed in 0.125260 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表