博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Lua基本语法-lua与C#的交互(相当简单详细的例子)
阅读量:6938 次
发布时间:2019-06-27

本文共 9985 字,大约阅读时间需要 33 分钟。

lua脚本 与 C#的交互


本文提供全流程,中文翻译。
Chinar坚持将简单的生活方式,带给世人!
(拥有更好的阅读体验 —— 高分辨率用户请根据需求调整网页缩放比例)



1

Lua And C# —— Lua 和 C#的交互准备工作

早期 Lua C# 之间的交互,需要用Lua官方做好的接口 LuaInterface.dll 等文件来实现

文件的下载直接跳转Lua官方网站:完成下载

点击 luainterface 链接 ↓↓

这里写图片描述

点击 1.5.3 链接 开始下载

这里写图片描述

下载完成后解压压缩文件,并打开 Built 文件夹

目录中的3个文件: lua51.dll LuaInterface.dll luanet.dll 是暂时需要用到的

这里写图片描述

打开VS,创建一个控制台脚本

这里写图片描述

将下载好的 LuaInterface.dll 文件拖到项目中

并按照步骤添加引用

图中我没有 using LuaInterface; 请自己添加上

这里写图片描述

找到项目中的目录,并将下载好的 lua51.dll luanet.dll 两个文件,拷贝到DeBug文件目录中

这里写图片描述


2

C# Create Lua —— 用C#在lua环境中编写lua

用简单的控制台程序 测试,输出

举个栗子黑白88

using System;using LuaInterface; //引用命名空间namespace ChinarTest{    ///     /// 测试类    ///     class Program    {        static void Main(string[] args)         {            Lua lua    = new Lua();        //创建一个lua解释器            lua["num"] = 66;               //用C#脚本在lua环境中,创建一个变量            lua["str"] = "chinar";         //用C#脚本在lua环境中,创建一个字符串变量            Console.WriteLine(lua["num"]); //输出            Console.WriteLine(lua["str"]); //输出            Console.ReadKey();             //等待输入        }    }}

输出结果:

66chinar

3

lua.DoString —— 在C#脚本中编写Lua脚本

lua.DoString() 用于创建代码段

举个栗子黑白88

using System;using LuaInterface; //引用命名空间namespace ChinarTest{    ///     /// 测试类    ///     class Program    {        static void Main(string[] args)        {            Lua lua = new Lua();                              //创建一个lua解释器            lua.DoString("num=666");                          //用C#脚本在lua环境中,创建一段lua脚本:num=666            lua.DoString("str='chianr666'");                  //用C#脚本在lua环境中,创建一段lua脚本:str='chianr666'            object[] values = lua.DoString("return num,str"); //用一个object数组 去接受返回值            foreach (var value in values)                     //遍历 values 数组中的元素            {                Console.WriteLine(value); //输出            }            Console.ReadKey(); //等待输入        }    }}

输出结果:

666chianr666

4

lua.DoFile —— 用C#加载Lua脚本文件

lua.DoFile() 用于找到目录中的Lua文件,并加载

需要将写好的Lua文件拖到项目中,并且修改属性为 :如果较新则复制 / 始终复制

否则会出现找不到文件的 报错信息

不会的请看下图

这里写图片描述

举个栗子黑白88

using System;using LuaInterface; //引用命名空间namespace ChinarTest{    ///     /// 测试类    ///     class Program    {        static void Main(string[] args)        {            Lua lua = new Lua();      //创建一个lua解释器            lua.DoFile("Chinar.lua"); //加载lua文件 —— lua.DoFile(文件名)            Console.ReadKey();        //等待输入        }    }}

下边是 Chinar.lua 文件

print('I am Chianr')MyTable={
1,22,333,4444,55555,666666}print(table.concat(MyTable)..'I am Chianr')

输出结果:

I am Chianr122333444455555666666I am Chianr

5

lua.RegisterFunction —— 将C#中的函数/方法 写入到Lua脚本中

lua.RegisterFunction() 用于将C#中的函数/方法 写入到Lua脚本中

注册方法

lua.RegisterFunction (注册到Lua中以后方法的名称,程序对象,程序的类型program.GetType().(传入C#中的方法名:需要是公有方法))

注册静态方法

lua.RegisterFunction (注册到Lua中以后方法的名称,空,程序的类型 typeof(Program).(传入C#中的方法名:需要是公有方法))

注册的方法必须是 public ,否则会找不到

举个栗子黑白88

using System;using LuaInterface; //引用命名空间namespace ChinarTest{    ///     /// 测试类    ///     class Program    {        static void Main(string[] args)        {            Lua     lua     = new Lua();     //创建一个lua解释器            Program program = new Program(); //声明一个对象            //lua.RegisterFunction 注册方法(注册到Lua中以后方法的名称,程序对象,程序的类型program.GetType().(传入C#中的方法名:需要是公有方法))            lua.RegisterFunction("LuaChinarTest", program, program.GetType().GetMethod("ChinarTest"));            //然后用lua.DoString(Lua中方法名())调用测试            lua.DoString("LuaChinarTest()");            //lua.RegisterFunction 注册静态方法(注册到Lua中以后方法的名称,空,程序的类型 typeof(Program).(传入C#中的方法名:需要是公有方法))            lua.RegisterFunction("LuaChinarStaticTest", null, typeof(Program).GetMethod("ChinarStaticTest"));            //然后用lua.DoString(Lua中静态方法名())调用测试            lua.DoString("LuaChinarStaticTest()");            Console.ReadKey(); //等待输入        }        ///         /// 一个测试方法        ///         public void ChinarTest()        {            Console.WriteLine("这是一个空方法");        }        ///         /// 一个静态测试方法        ///         public static void ChinarStaticTest()        {            Console.WriteLine("这个一个静态空方法");        }    }}

输出结果:

这是一个空方法这个一个静态空方法

6

require —— Lua中引用C#中的类

Lua 调用 C# 的类需要: LuaInterface.dll luanet.dll

luanet.dll 拷贝到工程 DeBug 输出目录中

lua 脚本中就不需要使用 package.cpath require

这点,在第一步 配置引用信息的时候,就做过了,如果没有做的报错了。请返回第一步

报错点1:

require “luanet” :如果DeBug中有luanet.dll文件,则不需要在Lua脚本中再次引用

否则会报错:

“LuaInterface.LuaException”类型的未经处理的异常在 LuaInterface.dll 中发生,其他信息: error loading module ‘luanet’ from file ‘.\luanet.dll’

报错点2:

另外,修改 ChinarClass.lua 的属性后,一定要保存,不然还会报错找不到文件

举个栗子黑白88

using System;using LuaInterface; //引用命名空间namespace ChinarTest{    ///     /// 测试类    ///     class Program    {        static void Main(string[] args)        {            Lua lua = new Lua();           //创建一个lua解释器            lua.DoFile("ChinarClass.lua"); //Lua引用C#中的类            Console.ReadKey();             //等待输入        }        public int    ChinarNum = 60;       //整形变量        public string Name      = "Chinar"; //字符串变量        ///         /// 用来让Lua脚本测试的方法        ///         public void ChinarTestFun()        {            Console.WriteLine("你好,Chinar");        }        ///         /// Ref方法,参数        ///         ///         ///         public void TestRef(string name, ref int count)        {            Console.WriteLine(name);            Console.WriteLine(count);            count = name.Length;        }        ///         /// Out方法,参数        ///         ///         ///         public void TestOut(string name, out int count)        {            Console.WriteLine(name);            count = name.Length;        }    }}

输出结果:

ProxyType(System.Int32): 46104728- - - - - - - - - - - - - - - - - - - - - - - - - -60你好,Chinarchinar.funnil     10chinar.fun8nil     10

7

All —— 全脚本数据

整个脚本项目

1个C#脚本 2个Lua脚本

举个栗子黑白88

using System;using LuaInterface; //引用命名空间namespace ChinarTest{    ///     /// 测试类    ///     class Program    {        static void Main(string[] args)        {            Lua lua = new Lua(); //创建一个lua解释器            lua["num"] = 66;               //用C#脚本在lua环境中,创建一个变量            lua["str"] = "chinar";         //用C#脚本在lua环境中,创建一个字符串变量            Console.WriteLine(lua["num"]); //输出            Console.WriteLine(lua["str"]); //输出            lua.DoString("num=666");                          //用C#脚本在lua环境中,创建一段lua脚本:num=666            lua.DoString("str='chianr666'");                  //用C#脚本在lua环境中,创建一段lua脚本:str='chianr666'            object[] values = lua.DoString("return num,str"); //用一个object数组 去接受返回值            foreach (var value in values)                     //遍历 values 数组中的元素            {                Console.WriteLine(value); //输出            }            lua.DoFile("Chinar.lua"); //加载lua文件 —— lua.DoFile(文件名)            Program program = new Program(); //声明一个对象            //lua.RegisterFunction 注册方法(注册到Lua中以后方法的名称,程序对象,程序的类型program.GetType().(传入C#中的方法名:需要是公有方法))            lua.RegisterFunction("LuaChinarTest", program, program.GetType().GetMethod("ChinarTest"));            //然后用lua.DoString(Lua中方法名())调用测试            lua.DoString("LuaChinarTest()");            //lua.RegisterFunction 注册静态方法(注册到Lua中以后方法的名称,空,程序的类型 typeof(Program).(传入C#中的方法名:需要是公有方法))            lua.RegisterFunction("LuaChinarStaticTest", null, typeof(Program).GetMethod("ChinarStaticTest"));            //然后用lua.DoString(Lua中静态方法名())调用测试            lua.DoString("LuaChinarStaticTest()");            lua.DoFile("ChinarClass.lua"); //Lua引用C#中的类            Console.ReadKey(); //等待输入        }        ///         /// 一个测试方法        ///         public void ChinarTest()        {            Console.WriteLine("这是一个空方法");        }        ///         /// 一个静态测试方法        ///         public static void ChinarStaticTest()        {            Console.WriteLine("这个一个静态空方法");        }        public int    ChinarNum = 60;       //整形变量        public string Name      = "Chinar"; //字符串变量        ///         /// 用来让Lua脚本测试的方法        ///         public void ChinarTestFun()        {            Console.WriteLine("你好,Chinar");        }        ///         /// Ref方法,参数        ///         ///         ///         public void TestRef(string name, ref int count)        {            Console.WriteLine(name);            Console.WriteLine(count);            count = name.Length;        }        ///         /// Out方法,参数        ///         ///         ///         public void TestOut(string name, out int count)        {            Console.WriteLine(name);            count = name.Length;        }    }}

Chinar.lua 文件

print('I am Chianr')MyTable={
1,22,333,4444,55555,666666}print(table.concat(MyTable)..'I am Chianr')

ChinarClass.lua 文件

-- 如果DeBug中有luanet.dll文件,则不需要再次引用-- require "luanet"-- 加载CLR类型("命名空间")luanet.load_assembly("System")-- 加载命名空间下的类Int32 = luanet.import_type("System.Int32")-- 输出print(Int32)print('- - - - - - - - - - - - - - - - - - - - - - - - - - ')-- 加载CLR类型("命名空间"ChinarTest)luanet.load_assembly("ChinarTest")-- 加载命名空间下的类ProgramPro=luanet.import_type("ChinarTest.Program")-- 实例化一个类对象pro=Pro()-- 输出print(pro.ChinarNum)-- 调用C#中的方法pro:ChinarTestFun()-- 调用Out方法,out参数不需要传入值,会直接返回类型为一个:表-- 由于C#那边是一个空返回值的方法,所以第一个返回为空-- 第二个返回 out参数void,stringCount=pro:TestOut("chinar.fun")print(void,stringCount)-- Ref参数void1,stringCount1=pro:TestRef("chinar.fun",8)print(void1,stringCount1)

输出结果:

66chinar666chianr666I am Chianr122333444455555666666I am Chianr这是一个空方法这个一个静态空方法ProxyType(System.Int32): 12289376- - - - - - - - - - - - - - - - - - - - - - - - - -60你好,Chinarchinar.funnil     10chinar.fun8nil     10

8

Error —— 常见报错点

报错点1:

require “luanet” :如果DeBug中有luanet.dll文件,则不需要在Lua脚本中再次引用

否则会报错:

“LuaInterface.LuaException”类型的未经处理的异常在 LuaInterface.dll 中发生,其他信息: error loading module ‘luanet’ from file ‘.\luanet.dll’

报错点2:

另外,修改 ChinarClass.lua 的属性后,一定要保存,不然还会报错找不到文件

报错点3:

注册的方法必须是 public ,否则会找不到

报错点4:

需要将写好的Lua文件拖到项目中,并且修改属性为 :如果较新则复制 / 始终复制

否则会出现找不到文件的 报错信息

报错点5:

找到项目中的目录,并将下载好的 lua51.dll luanet.dll 两个文件,拷贝到DeBug文件目录中

这一步,在第一步就做好,一步到位!


70
Chinar

直接Down下来运行即可


END

本博客为非营利性个人原创,除部分有明确署名的作品外,所刊登的所有作品的著作权均为本人所拥有,本人保留所有法定权利。违者必究

对于需要复制、转载、链接和传播博客文章或内容的,请及时和本博主进行联系,留言,Email: ichinar@icloud.com
对于经本博主明确授权和许可使用文章及内容的,使用时请注明文章或内容出处并注明网址

转载于:https://www.cnblogs.com/chinarbolg/p/9601452.html

你可能感兴趣的文章
上网不掉钱
查看>>
我的友情链接
查看>>
Intruder reporting tool (for ssh remote login)
查看>>
创建cocopods库(swift版)
查看>>
linux启动不了,无法进入rescure模式,Mount: could not find filesystem '/dev/root
查看>>
TCP拥塞控制机制
查看>>
hdfs运维中遇到的问题记录
查看>>
手机屏幕适配
查看>>
软件测试LR通用性能分析流程
查看>>
如何升级phpmyadmin
查看>>
解决 phpmyadmin #2002 无法登录 MySQL 服务器
查看>>
hibernate添加时间问题
查看>>
要看的
查看>>
我的Git忽略文件
查看>>
Maven学习总结(六)——Maven与Eclipse整合
查看>>
我的友情链接
查看>>
深入浅出CChart 每日一课——第九课 实时数据显示,期中考试
查看>>
深入浅出CChart 每日一课——第十三课 似曾相识之云图,乱花渐欲迷人眼
查看>>
SpringMVC权限管理
查看>>
nginx Etag模块
查看>>