您的位置:首页 > 编程语言 > Lua

腾讯XLua 03-CSharp Invoke Lua

2017-01-15 23:42 666 查看
using UnityEngine;
using System.Collections;
using XLua;

public class MyInvokeLua : MonoBehaviour {
//创建一个接口 用于生成 调用函数
[CSharpCallLua]
//这是一个生成调用函数用的标签 生成CSharp调用Lua,加这标签
public interface ICalc {
int Add(int a, int b);
int Mult { get; set; }
}

[CSharpCallLua]
//(1)在方法声明中的 params 关键字之后不允许任何其他参数,并且在方法声明中只允许一个 params 关键字。
//(2)该参数必须标识一个一维数组,但类型不限,对该参数传递null或者0个数目的数组的引用都是合法的*
public delegate ICalc CalcNew(int mult, params string[] arg);
//创建一个元表
private string 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
{
public int Add(int a, int b)
{
#if THREAD_SAFT || HOTFIX_ENABLE
lock (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的元素放入栈顶,判断得到的是否是function
if(!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
}

public int Mult
{

get
{
#if THREAD_SAFT || HOTFIX_ENABLE
lock (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_ENABLE
lock (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_ENABLE
lock (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
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  XLua