Unity热更新技术学习——LuaInterface

概述

LuaInterface 源码下载:https://github.com/LuaDist/luainterface

LuaInterface是一个CLR库,以 .dll 的形式呈现。

要想在Unity中使用Lua,必须解决C#和Lua的交互问题,或者说CLR(即windows平台为人熟知的.Net或者linux上的Mono)和Lua的交互。LuaInterface为了解决这个问题,最重要的就是做了两件事情:

  • LuaInterface 允许Lua脚本实例化CLR对象并使用它,甚至创建新的CLR对象
  • 允许CLR应用程序使用LuaInterface嵌入一个Lua解释器,从而你可以通过书写lua代码扩展CLR应用程序

LuaInterface 并不能直接与lua交互,或者说,直接解释lua。它需要借助lua解释器的源码(一众C语言写的代码)来帮助解释lua,而C#层需要利用平台调用技术去使用Lua解释器提供的api,从而与lua交互。所以这里C其实充当了一个中间层,lua解释器的源码被编译成了一个动态链接库,供C#层调用。最终整个LuaInterface也会编译成一个新的动态链接库,而暴露到库外的API都由C#层实现。

C#: Luainterface
C: lua interprete, in the form of dll
lua: lua source

想要了解什么是CLR,请参考:这里
想要了解什么是平台调用(P/Invoke)技术,请参考:这里

使用LuaInterface

LuaInterface Binary下载:http://luaforge.net/projects/luainterface/

从上面的网站中找到最新的LuaInterface压缩包,解压,得到以下两个文件:

  • 一份Native库,lua51.dll由lua源码编译而来,它提供了lua解释器的一系列C API
  • 一份托管库,LuaInterface.dll由LuaInterface的C#代码部分编译而来,它借助lua51.dll去解释lua源码,并向外提供真正可用的C#层API,当我们在编写C#代码时,代码需要引用的库只有LuaInterface.dll
    在这里插入图片描述
    使用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属性。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup useLegacyV2RuntimeActivationPolicy="true"> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
    </startup>
</configuration>

程序输出如下:
在这里插入图片描述
在上面例子中,我们做了以下几件事情:

  • 实例化了一个lua解释器,帮助我们运行lua代码
  • 使用解释器实例的索引器在C#层创建lua对象,包括字符串,数字和lua表
  • 使用lua.DoString()方法执行一段lua源码,并获得它的返回(如果源码中有return语句的话)

为此,我们已经见识到了LuaInterface如何完美地运作了。当然,LuaInterface不止如此。

LuaInterface教程

正如上面所述,LuaInterface为了解决Lua和CLR的交互完成了两件事情:允许从CLR访问Lua,以及允许从Lua访问CLR。

下面来看看这两件事情具体是如何运用的。不过在此之前,我们还需要搞清楚,这两种不同语言之间的变量类型是如何映射的。

类型转化
C#类型Lua类型
nullnil
System.Doublenumbers
System.Stringstrings
System.Booleanbooleans
LuaTabletable
LuaFunctionfunction
LuaUserDatauserdata
从CLR访问Lua

正如上面的示例代码一样:

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源码
从Lua访问CLR

最新的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()

这是一个官方的实例。将之保存为一个lua脚本,然后在C#里使用DoFile()方法执行它,你会得到如下结果:
在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值