开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第23天,点击查看活动详情
Lua是一种很好的扩展性语言,Lua解释器被设计成一个很容易嵌入到宿主程序的库。LuaInterface则用于实现Lua和CLR的混合编程 。
一、C#调用Lua
1.1 编译tolua.dll
tolua C 起到承上启下的作用,是C#和lua的中间层,在和C#交互方面,作为非c#托管代码,会提供一些函数让c# DllImport,c#会通过Marshal等与非托管代码交互
还有一些lua的扩展库,比如 cjson、LuaSocket、sqlite3、lpeg、bit、pbc等手机游戏常用库,这些库扩展了lua的能力。
windows平台叫做tolua.dll;
android叫做libtolua.so;
mac平台叫tolua.bundle;
而iOS平台由于不允许使用动态库,所以会编译成静态库libtolua.a。
编译出tolua.dll,复制到unity的Plugins文件夹下,然后就可以在C#层以DllImport导入接口,然后就可以在C#层调用到C层的方法了。
1.2 C#调用Lua文件
//C# 层调用 lua层 demo
void Start()
{
LuaState m_LuaState= new LuaState();//建立Lua虚拟机
m_LuaState.Start();//启动虚拟机
//1. 使用string调用Lua
string luaString = @"print('这是一个使用DoString的Lua程序')";
m_LuaState.DoString(luaString);
//2. 使用文件调用Lua
//手动添加一个lua文件搜索地址
m_LuaState.AddSearchPath(string.Format("{0}/{1}", Application.dataPath, "Lua"));
//读取main.lua文件
m_LuaState.DoFile("main");// 方法1
m_LuaState.Require(luaFile);// 方法2
m_LuaState.Dispose();//使用完毕回收虚拟机
Debug.LogFormat("当前虚拟机状态:{0}", null == m_LuaState);//验证虚拟机状态
}
ToLua直接调用Lua代码的方式有两种:DoString、DoFile。这两个只是运行一次,运行之后保存在缓存中
此外还有一个Require方法,这个方法和前两个方法不同的是,ToLua会将调用的Lua文件载入Lua栈中
在上述代码中要注意,使用DoFile和Require方法时,要手动给目标文件添加一个文件搜索位置。
1.3 C#中调用Lua变量/函数
上面实现了C#调用Lua文件和string,其实对于ToLua而且,直接调用string和文件并没有本质区别,最后都会转换成byte[]进行载入。
接下来实现一下ToLua调用指定Lua变量和函数
//找到mian方法并调用
LuaFunction main = m_LuaState.GetFunction("main");
main.Call();
main.Dispose();
main = null;
二、Lua调用C#
在Lua中访问C#中的属性和方法。
Lua代码中,访问C#对象的属性的方式和访问table的键索引一样,比如obj.name或者 obj["name"]。
Lua代码中,访问C#对象的普通函数的方式和调用table的函数一样,比如obj:method1()。
luanet.load_assembly("lelelua")
Program=luanet.import_type("lelelua.Program")
program1=Program()
print(program1.name)
program1:TestMethod()
public string name = "乐乐爱学习";
public void TestMethod()
{
Console.WriteLine("C#中的方法");
}
在Lua中访问C#中的方法-特殊情况,注意有两个返回值
luanet.load_assembly("lelelua")
Program=luanet.import_type("lelelua.Program")
program1=Program()
void,strlength=program1:TestOut("leleaixuexi")
print(strlength)
public void TestOut(string name, out int count)
{
count = name.Length;
}
当函数中有out或ref参数时,out参数和ref参数和函数的返回值一起返回,并且调用的时候,out参数不需要传入。
ref参数需要传入,返回一个table有两个值(value1,value2)。
当有重载函数的时候,调用函数会自动匹配第一个能匹配的函数。
可以使用get_method_bysig函数得到C#中指定类的指定参数的函数用法。
luaMethod= get_method_bysig(Obj,"CSharpMethod","System.String")
luaMethod("siki")
在Lua中注册C#中的事件委托(event delegate)。
在Lua中通过Add方法或者Remove方法把一个Lua的函数注册或者注销从C#中的事件委托中。
function method()
end
obj.SomeEvent:Add(methodname(不用带引号))