|
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 } |
|