LuaInterface是一个CLR库,以 .dll 的形式呈现。
要想在Unity中使用Lua,必须解决C#和Lua的交互问题,或者说CLR(即windows平台为人熟知的.Net或者linux上的Mono)和Lua的交互。LuaInterface为了解决这个问题,最重要的就是做了两件事情:
CLR通过平台调用(Platform/Invoke)技术将Lua解释器编译为一个动态链接库,然后使用的时候将之与CLR应用程序本身链接,这个动态链接库,就是LuaInterface。当然,解释器只是LuaInterface中的一部分。
想要了解什么是CLR,请参考:这里
想要了解什么是平台调用(P/Invoke)技术,请参考:这里
LuaInterface下载:http://luaforge.net/projects/luainterface/
从上面的网站中找到最新的LuaInterface压缩包,解压,得到以下文件:
使用visual studio新建一个C#控制台程序,为其添加上述两个 dll 引用。
然后书写如下代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using LuaInterface;
namespace TestLuaInterface
{
class Program
{
static void Main(string[] args)
{
Lua lua = new Lua(); // 实例化一个lua解释器
lua["name"] = "chentianqin"; // 创建一个lua字符串
lua["age"] = 23; // 创建一个lua数字
lua.NewTable("people"); // 创建一个lua表
lua.DoString(@"print('This is run by lua.DoString!!!')");
lua.DoString(@"print(name)");
lua.DoString(@"print(age)");
lua.DoString(@"people[1] = 'Tom';print(people[1]);");
object[] values = lua.DoString("return name, age");
string name = (string)values[0];
double age = (double)values[1];
LuaTable table = (LuaTable)lua["people"];
Console.WriteLine("\n********以下为C#层打印的东西********\n");
Console.WriteLine("name = " + name);
Console.WriteLine("age = " + age);
Console.WriteLine("table = " + table[1]);
Console.ReadLine();
}
}
}
点击运行,如果报System.IO.FileLoadException:"混合模式程序集...
的错误,请为App.config文件里面的startup添加useLegacyV2RuntimeActivationPolicy
属性。
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
startup>
configuration>
lua.DoString()
方法执行一段lua源码,并获得它的返回(如果源码中有return语句的话)为此,我们已经见识到了LuaInterface如何完美地运作了。当然,LuaInterface不止如此。
正如上面所述,LuaInterface为了解决Lua和CLR的交互完成了两件事情:允许从CLR访问Lua,以及允许从Lua访问CLR。
下面来看看这两件事情具体是如何运用的。不过在此之前,我们还需要搞清楚,这两种不同语言之间的变量类型是如何映射的。
C#类型 | Lua类型 |
---|---|
null | nil |
System.Double | numbers |
System.String | strings |
System.Boolean | booleans |
LuaTable | table |
LuaFunction | function |
LuaUserData | userdata |
正如上面的示例代码一样:
Lua lua = new Lua(); // 创建一个Lua解释器实例
lua["num"] = 2; // 使用索引器去创建一个lua变量
lua["str"] = "a string";
lua.NewTable("tab"); // 使用NewTable()去创建一张lua表
double num = (double)lua["num"]; // 使用索引器去访问一个lua变量
string str = (string)lua["str"];
lua.DoFile("test.lua"); // 使用DoFile()去运行一个lua脚本
object [] rets = lua.DoString("return num, str;"); // 使用DoString()去执行一段lua源码
最新的LuaInterface(version >= 2.0.1)内置的解释器包含了一套库,里面自带一个全局的luanet
模块。这个模块允许你加载CLR的程序集和CLR类型。
luanet.load_assembly("System.Windows.Forms") -- 使用load_assembly加载CLR程序集
luanet.load_assembly("System.Drawing")
Form=luanet.import_type("System.Windows.Forms.Form") -- 使用import_type导入CLR类型
Button=luanet.import_type("System.Windows.Forms.Button")
Point=luanet.import_type("System.Drawing.Point")
form1=Form() -- 导入之后就可以正常使用类型进行实例化和访问成员方法
button1=Button()
button2=Button()
function handleClick(sender,data)
if sender.Text=="OK" then -- 使用点句号 . 访问成员变量
sender.Text="Clicked"
else
sender.Text="OK"
end
button1.MouseUp:Remove(handler) -- 使用冒号 : 访问成员方法
print(sender:ToString())
end
button1.Text = "OK"
button1.Location=Point(10,10)
button2.Text = "Cancel"
button2.Location=Point(button1.Left, button1.Height + button1.Top + 10)
handler=button1.MouseUp:Add(handleClick)
form1.Text = "My Dialog Box"
form1.HelpButton = true
form1.MaximizeBox=false
form1.MinimizeBox=false
form1.AcceptButton = button1
form1.CancelButton = button2
form1.Controls:Add(button1)
form1.Controls:Add(button2)
form1:ShowDialog()