首页 > 编程知识 正文

tolua github,Lua框架

时间:2023-05-06 03:34:27 阅读:227049 作者:2612

          文章参考来源:https://blog.csdn.net/heyuchang666/article/details/50722658

           LuaInterface.Lua类是CLR访问Lua解释器的主要接口,一个LuaInterface.Lua类对象就代表了一个Lua解释器(或Lua执行环境),Lua解释器可以同时存在多个,并且它们之间是完全相互独立的。简单来说,LuaInterface就是用于Lua和C#交互的工具。

      LuaInterface的下载地址:http://luaforge.net/projects/luainterface/。下载后解压即可获取两个dll文件:luanet.dll和luainterface.dll。

          我使用的是VS2017新建的工程。加入两个dll文件的引用后,引用luainterface命名空间即可。此时如果实例化一个解释器实例,运行时会报错,如下:

这个问题的解决可以参见:https://blog.csdn.net/bbnbf/article/details/7010551。

      解决问题后,开始学习之路。

      lua和C#的交互无非就是lua调用C#的字段,方法。C#调用lua的方法,执行lua脚本。

C#执行lua脚本(创建变量,执行方法等)

    可以使用索引操作符[]来创建变量,NewTable()用于创建一个空表格,要修改数据,需要用到lua对表的操作。例如:

class Program{ static void Main(string[] args) { // 创建一个lua解释器。每个lua实例都是相互独立的 Lua lua = new Lua(); // lua的索引操作[]可以创建,访问,修改global域,括号里面是变量名 // 创建global域num和str两个变量 lua["num"] = 2; lua["str"] = "this is a string"; // 创建空的table lua.NewTable("tab"); }}

 DoString()方法可以执行一段lua代码,参数是一段string类型的lua代码片段。

class Program { static void Main(string[] args) { // 创建一个lua解释器。每个lua实例都是相互独立的 Lua lua = new Lua(); // lua的索引操作[]可以创建,访问,修改global域,括号里面是变量名 // 创建global域num和str两个变量 lua["num"] = 2; lua["str"] = "this is a string"; // 创建空的table lua.NewTable("tab"); // 执行lua脚本,这两个方法都会返回object[] 记录脚本的执行结果 lua.DoString("num = 100, print('i an a string')"); lua.DoString("local a = {1,2,3} " + "for k,v in pairs(a) do " + "print(k,v) " + "end"); }}

执行结果如下,可以看出,我们正确遍历了table。只不过,写起来有点怪怪的。

Dostring()方法会返回一个object[]类型的数组。可以获取lua中执行结果的返回。如下所示:

会发现,没有获取到表a的值。这是因为DoString()方法是执行的lua代码片段。这里的a和上一段的表a不是同一个变量。如果改成“return a = 10”,那么就会打印出结果10。

       DoFile()方法用于执行lua脚本,参数是lua脚本的路径,如下:

       LuaIntrface自动对应Lua和CLR中的一些基础类型
  [nil, null]
  [string, System.String]
  [number, System.Double]
  [boolean, System.Boolean]
  [table, LuaInterface.LuaTable]
  [function, LuaInterface.LuaFunction]
以上对应关系反之亦然。如下图所示:

 Lua执行C#脚本

     RegisterFunction方法用来将CLR函数注册进Lua解释器,供Lua代码调用。该方法接收三个参数:string path, object target, MethodBase function。path指注册进lua的函数在lua中的名字, target指方法的对象实例,function指方法。如下,我们新建一个类,里面写一些打印输出方法:

注册进lua后,用DoString方法执行:

可以看到,方法被正确执行了。另外,我们看到,静态方法,第二个参数是不用传递的(null)。这里我们使用GetMethod()来获取类中的方法。RegisterFunction的返回值类型是LuaFunction类型。接收的是lua中的函数。如下,我们在LuaCallCSharpTest类中新增一个方法:

LuaFunction类型对应的是lua种的function。使用Call方法,就可以执行lua中的该方法。

CLR from Lua

       这里我们在外部编写lua脚本,然后在C#中调用。Luainterface主要提供了下面几个方法:    

       luanet.load_assembly函数:加载CLR程序集;

  luanet.import_type函数:加载程序集中的类型;

  luanet.get_constructor_bysig函数:显示获取某个特定的构造函数;

我们可以通过这几个方法。加载C#代码到lua中去。加载指定程序集下面的指定类。

C#测试代码如下,我们写了几个不同的构造函数,然后尝试在lua中进行匹配。

 编写lua脚本,脚本我是放在项目工程目录下的,

也可以将luanet.dll 拷贝到工程 DeBug 输出目录中,然后需要将写好的Lua文件拖到项目中,并且修改属性为 :如果较新则复制 / 始终复制。否则会出现找不到文件的 报错信息。这样也同样不需要require了。

lua脚本如下:

程序集的名字可以在项目中进行设置,在菜单的项目->XXX属性下面就可以设置了。import_type中就是命名空间的名字了。

        从上面的构造函数的匹配可以看出,LuaInterface匹配构造函数的规律:

  LuaInterface匹配第一个能够匹配的构造函数,在这个过程中,numerical string(数字字符串)会自动匹配number,而number可以自动匹配string,所以CSharpFromLua(3)匹配到了参数为string的构造函数。

  如果一定要手动匹配某个构造函数,则可以使用luanet.get_constructor_bysic函数。

访问C#对象和字段

       Lua代码中,访问CLR类型对象的字段的方式和访问table的键索引一样,比如button1.Text、button["Text"];

  Lua代码中,访问CLR类型对象的函数的方式和调用table的函数一样,比如form:ShowDialog()。

C#测试代码和lua代码如下:

使用DoFile()执行lua文件,输出结果如下:

我们已经通过构造函数实例化了该类,所以只要直接调用方法即可。这里使用冒号操作符来调用类的方法,使用[]来访问类的字段,这一点和访问table是一样的。冒号和点号的使用区别可以在网上查到。

       其他还有一些特殊情况:

       当有重载方法时,匹配的规则就可上面介绍的一样。可以使用luanet.get_method_bysig方法来匹配指定的方法。如下图:

数字字符串类型的参数,会自动匹配int。而普通的字符串则会自动匹配string参数。

       当函数有out或ref参数时,out参数和ref参数和函数的返回值一起返回,并且调用函数时out参数不需要传入,可以使用别的变量来接受该out参数,比如:

对于ref参数,如下:

可以看到,其在lua中的用法和out参数是一样的。但是,传递进去的参数并没有变化,这一点和在C#中的用法是不一样的。

事件处理,添加和删除事件委托

     LuaInterface为Event提供了Add和Remove函数来注册和移除事件处理函数。Add函数传入一个Lua函数,将其转换为一个CLR委托(delegate),并返回这个委托。如下:

 

 

CSS中div滚动条样式如何设置怎么查看电脑配置

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。