Lua基本语法-lua与C#的交互(相当简单详细的例子)

lua脚本 与 C#的交互


本文提供全流程,中文翻译。

Chinar坚持将简单的生活方式,带给世人!

(拥有更好的阅读体验 —— 高分辨率用户请根据需求调整网页缩放比例)



  • 1
    • Lua And C# —— Lua 和 C#的交互准备工作
  • 2
    • C# Create Lua —— 用C#在lua环境中编写lua
  • 3
    • lua.DoString —— 在C#脚本中编写Lua脚本
  • 4
    • lua.DoFile —— 用C#加载Lua脚本文件
  • 5
    • lua.RegisterFunction —— 将C#中的函数/方法 写入到Lua脚本中
  • 6
    • require —— Lua中引用C#中的类
  • 7
    • All —— 全脚本数据
  • 8
    • Error —— 常见报错点

1

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


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


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

点击 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
{/// <summary>/// 测试类/// </summary>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();             //等待输入}}
}

输出结果:

66
chinar

3

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


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

举个栗子黑白88

using System;
using LuaInterface; //引用命名空间namespace ChinarTest
{/// <summary>/// 测试类/// </summary>class Program{static void Main(string[] args){Lua lua = new Lua();                              //创建一个lua解释器lua.DoString("num=666");                          //用C#脚本在lua环境中,创建一段lua脚本:num=666lua.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(); //等待输入}}
}

输出结果:

666
chianr666

4

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


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

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

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

不会的请看下图

这里写图片描述

举个栗子黑白88

using System;
using LuaInterface; //引用命名空间namespace ChinarTest
{/// <summary>/// 测试类/// </summary>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 Chianr
122333444455555666666I 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
{/// <summary>/// 测试类/// </summary>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(); //等待输入}/// <summary>/// 一个测试方法/// </summary>public void ChinarTest(){Console.WriteLine("这是一个空方法");}/// <summary>/// 一个静态测试方法/// </summary>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
{/// <summary>/// 测试类/// </summary>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"; //字符串变量/// <summary>/// 用来让Lua脚本测试的方法/// </summary>public void ChinarTestFun(){Console.WriteLine("你好,Chinar");}/// <summary>/// Ref方法,参数/// </summary>/// <param name="name"></param>/// <param name="count"></param>public void TestRef(string name, ref int count){Console.WriteLine(name);Console.WriteLine(count);count = name.Length;}/// <summary>/// Out方法,参数/// </summary>/// <param name="name"></param>/// <param name="count"></param>public void TestOut(string name, out int count){Console.WriteLine(name);count = name.Length;}}
}

输出结果:

ProxyType(System.Int32): 46104728
- - - - - - - - - - - - - - - - - - - - - - - - - -
60
你好,Chinar
chinar.fun
nil     10
chinar.fun
8
nil     10

7

All —— 全脚本数据


整个脚本项目

1个C#脚本 2个Lua脚本

举个栗子黑白88

using System;
using LuaInterface; //引用命名空间namespace ChinarTest
{/// <summary>/// 测试类/// </summary>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=666lua.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(); //等待输入}/// <summary>/// 一个测试方法/// </summary>public void ChinarTest(){Console.WriteLine("这是一个空方法");}/// <summary>/// 一个静态测试方法/// </summary>public static void ChinarStaticTest(){Console.WriteLine("这个一个静态空方法");}public int    ChinarNum = 60;       //整形变量public string Name      = "Chinar"; //字符串变量/// <summary>/// 用来让Lua脚本测试的方法/// </summary>public void ChinarTestFun(){Console.WriteLine("你好,Chinar");}/// <summary>/// Ref方法,参数/// </summary>/// <param name="name"></param>/// <param name="count"></param>public void TestRef(string name, ref int count){Console.WriteLine(name);Console.WriteLine(count);count = name.Length;}/// <summary>/// Out方法,参数/// </summary>/// <param name="name"></param>/// <param name="count"></param>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")
-- 加载命名空间下的类Program
Pro=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)

输出结果:

66
chinar
666
chianr666
I am Chianr
122333444455555666666I am Chianr
这是一个空方法
这个一个静态空方法
ProxyType(System.Int32): 12289376
- - - - - - - - - - - - - - - - - - - - - - - - - -
60
你好,Chinar
chinar.fun
nil     10
chinar.fun
8
nil     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

Chinar的GitHub工程案例

直接Down下来运行即可


END

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

对于需要复制、转载、链接和传播博客文章或内容的,请及时和本博主进行联系,留言,Email: ichinar@icloud.com

对于经本博主明确授权和许可使用文章及内容的,使用时请注明文章或内容出处并注明网址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/255272.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

漫谈程序员系列:千奇百怪的程序员

干开发时间长了&#xff0c;遇见好多好玩儿的程序员。 看看你躺枪了没。 博客之星评选&#xff0c;点击投我一票&#xff0c;谢谢。投过了也可以点哦&#xff0c;每天都可以投投一票。 留一手 有个哥们儿&#xff0c;在一合资公司做程序员&#xff0c;能力挺强&#xff0c;写…

SCARA机器人与 DELTA机器人

1、SCARA机器人SCARA&#xff08;Selective Compliance Assembly Robot Arm&#xff0c;中文译名&#xff1a;选择顺应性装配机器手臂&#xff09;是一种圆柱坐标型的特殊类型的工业机器人。1978年&#xff0c;日本山梨大学牧野洋发明SCARA&#xff0c;该机器人具有四个轴和四个…

一直以来都没直视的轮播-_-

一直以来做项目碰到轮播图我都是去网站上找现成插件拿来用&#xff0c;现成的插件1是省时间&#xff0c;拿来改改尺寸改改参数就能直接用&#xff0c;2是现在的插件确实很强大&#xff0c;对于我一个刚刚学习前端的人来说&#xff0c;牛人写的轮播我看懂也要花些功夫&#xff0…

HALCON示例程序circles.hdev边界轮廓的圆形拟合

HALCON示例程序circles.hdev边界轮廓的圆形拟合 小哥哥小姐姐觉得有用点个赞呗&#xff01; 示例程序源码&#xff08;加注释&#xff09; 读入图片 read_image (Image, ‘double_circle’)窗口初始化 dev_close_window () get_image_size (Image, Width, Height) dev_open…

asp.net 微信企业号办公系统-流程设计--保存与发布

如果流程未设计完时可以先保存&#xff0c;以后再打开接着设计。点击工具栏上的保存按钮即可保存当前流程设计: 如果下次要接着设计&#xff0c;则可以打开该流程继续设计&#xff1a; 如果流程设计完成&#xff0c;可以点击安装按钮来发布流程&#xff0c;流程安装成功后即加入…

Canny边缘检测算法原理及其VC实现详解(二)

3、 Canny算法的实现流程 由于本文主要目的在于学习和实现算法&#xff0c;而对于图像读取、视频获取等内容不进行阐述。因此选用OpenCV算法库作为其他功能的实现途径&#xff08;关于OpenCV的使用&#xff0c;作者将另文表述&#xff09;。首先展现本文将要处理的彩色图片。 …

IDEA注册jar包使用和常用插件

IDEA注册jar包使用 点击获取下载地址或生成注册码 一、安装完成后&#xff0c;先不启动&#xff0c;首先如下图修改相关的地方。 二、启动IDEA&#xff0c;并且激活IDEA IDEA插件仓库 IntelliJ IDEA Plugins 一、Maven Helper 我一般用这款插件来查看maven的依赖树。在不使用此…

Android Monkey压力测试

一. JAVA环境的搭建 安装jdk-8u151-windows-x64,可以到官网或者应用中心下载.JAVA环境变量的搭建: 在"我的电脑"-"属性"-"高级"-"环境变量"中,点击新建,填写变量名为JAVA_HOME,变量值为JAVA安装的路径.在系统变量中找到Path,点击编辑,…

bzoj 4517: [Sdoi2016]排列计数

4517: [Sdoi2016]排列计数 Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 637 Solved: 396[Submit][Status][Discuss]Description 求有多少种长度为 n 的序列 A&#xff0c;满足以下条件&#xff1a;1 ~ n 这 n 个数在序列中各出现了一次若第 i 个数 A[i] 的值为 i&#x…

自制反汇编逆向分析工具 迭代第六版本 (五)

本工具从最初版的跳转分布图只为了更直观地分析反汇编代码的分支结构&#xff0c;第三版开始对直观图进行逆向分支代码的输出&#xff0c;第四版对分支输出策略的一些探索&#xff0c;第五版结合之前的探索进行改进。第六版在现在功能的基础上进行增强&#xff0c;利用第六版&a…

centos7搭建FTP服务器

1.   使用 yum 安装 vsftpd&#xff1a;yum install -y vsftpd 2.  启动 VSFTPD&#xff1a;systemctl start vsftpd.service 3.  启动后可监听到21端口&#xff1a;netstat -nltp | grep 21 4.  配置FTP权限&#xff1a;&#xff08;vsftpd.conf&#xff0c;修改前先备…

教你如何剖析源码

一、源码阅读需求 在学习中&#xff0c;我们会需要了解&#xff0c;学习&#xff0c;使用一个框架&#xff0c;一个新的函数库。在工作中&#xff0c;因为业务需求&#xff0c;因为性能问题&#xff0c;可能通过一个更高性能的工具&#xff0c;架构去优化我们的程序。 那么&…

php调用API支付接口(转自刘68)

首先访问 https://charging.teegon.com/ 注册账号&#xff0c; 找到开发配置 记下client_id和client_secret。 点击 天工开放平台 点击天工收银 点击 SDK下载与使用 选择php版下载 解压后获得 打开form.php这个是样板文件可以用它来测试是否成功&#xff0c;测试前需要先修…

单目相机标定原理

一&#xff0e;相机标定主要涉及三个坐标系&#xff1a;图像坐标系、摄像机坐标系和世界坐标系 【图像坐标系】 摄像机采集的图像变换为数字图像后&#xff0c;每副数字图像在计算机内为M x N数组&#xff0c;M行N列的图像中每一个元素&#xff08;pixel&#xff09;数值就是图…

Android开始之 activity_lifecycle和现场保护

生命周期&#xff1a; oncreate—onstart—onresume&#xff0c;--onpause--onstop&#xff0c;——onrestart——onstart——onresume&#xff0c;。。onpause。。。onstop。。。ondestroy 现在保护---保存系统状态 通过这个方法保存到数据库中或者xml中&#xff0c;&#xff…

Apache启动错误:could not bind to address[::]:443

Q&#xff1a;Windows环境下启动apache报错如下&#xff1a; 可是在httpd.conf文件中apache listen的明明是http 80端口&#xff0c;为什么会报443的错误&#xff1f; A&#xff1a;因为你的计算机安装了VM&#xff0c;所有有个vm的进程一直占用着443端口&#xff0c;在命令行下…

针孔相机拍摄的图像坐标和空间点的对应关系

一&#xff1a;摄像机成像原理 摄像机成像模型一般有三种&#xff1a;透镜投影模型&#xff08;小孔摄像机模型&#xff09;、正交投影模型和透视投影模型 光学中最基本的高斯成像公式&#xff1a;1/u 1/v 1/f (式一) 原理图如下&#xff1a; 二&#xff1a;认识三个…

粥做得好不好,全凭一个良心!

粥做得好不好&#xff0c;全凭一个良心&#xff01; 工作不也是凭良心么&#xff01; 文章中的红色字体表达了一切&#xff01; 霜降节气的到来&#xff0c;意味着冬季的临近&#xff0c;而霜降后气温的降低&#xff0c;利于蔬菜的淀粉沉淀&#xff0c;收浆后的莲藕也变得更为…

黑盒测试

引言&#xff1a; 什么是黑盒测试呢&#xff01;&#xff1f; 像我一样的测试小白就会望文生义了&#xff1a;对黑盒子测试 那么黑盒子是什么&#xff01;? 思考5秒后&#xff0c;得出了这样的答案&#xff1a;黑盒子就是黑色的盒子&#xff0c;嘿嘿&#xff01; 正文&#xf…

Expo大作战(十二)--expo中的自定义样式Custom font,以及expo中的路由RouteNavigation

简要&#xff1a;本系列文章讲会对expo进行全面的介绍&#xff0c;本人从2017年6月份接触expo以来&#xff0c;对expo的研究断断续续&#xff0c;一路走来将近10个月&#xff0c;废话不多说&#xff0c;接下来你看到内容&#xff0c;讲全部来与官网 我猜去全部机翻个人修改补充…