lua脚本 与 C#的交互


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

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

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



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

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

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() 用于创建代码段

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=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(); //等待输入
}
}
}

输出结果:

666
chianr666

4

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

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

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

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

不会的请看下图

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 ,否则会找不到

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 的属性后,一定要保存,不然还会报错找不到文件

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脚本

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=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(); //等待输入
} /// <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文件目录中

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




" role="presentation" style="position: relative;">

Chinar

Chinar的GitHub工程案例

直接Down下来运行即可


END

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


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


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

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

  1. Lua基础语法讲解

    Lua 是什么? Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能. Lua 是巴西里约热内卢天主教大学( ...

  2. 大体了解Lua的语法

    Lua 的语法比较简单,学习起来也比较省力,但功能却并不弱. 在Lua中,一切都是变量,除了关键字.请记住这句话. I. 首先是注释 写一个程序,总是少不了注释的. 在Lua中,你可以使用单行注释和多 ...

  3. Lua 基本语法

    学习Unity的ulua热更新插件就必须先学习lua的基本语法. 我们一起来学习Lua吧O(∩_∩)O. 首先搭建Lua运行环境Lua for windows 下载地址: http://www.cr1 ...

  4. 【转】Lua脚本语法说明简介

    Lua 的语法比较简单,学习起来也比较省力,但功能却并不弱. 所以,我只简单的归纳一下Lua的一些语法规则,使用起来方便好查就可以了.估计看完了,就懂得怎么写Lua程序了. 在Lua中,一切都是变量, ...

  5. Lua 脚本语法说明(转)

    Lua脚本语法说明(增加lua5.1部份特性) Lua 的语法比较简单,学习起来也比较省力,但功能却并不弱. 所以,我只简单的归纳一下Lua的一些语法规则,使用起来方便好查就可以了.估计看完了,就懂得 ...

  6. 通过lua栈了解lua与c的交互

    lua是如何执行的 其中分析.执行部分都是c语言实现的. lua与c的关系 lua的虚拟机是用c语言实现的,换句话说一段lua指令最终在执行时都是当作c语言来执行的,lua的global表,函数调用栈 ...

  7. Lua脚本语法说明(转)

    Lua脚本语法说明(增加lua5.1部份特性) Lua 的语法比较简单,学习起来也比较省力,但功能却并不弱. 所以,我只简单的归纳一下Lua的一些语法规则,使用起来方便好查就可以了.估计看完了,就懂得 ...

  8. Lua基本语法-书写规范以及自带常用函数

    Lua基本语法-书写规范和常用函数 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 1 String Ope ...

  9. Lua脚本语法说明(转):

    Lua脚本语法说明(增加lua5.1部份特性) 转自:http://www.cnblogs.com/ly4cn/archive/2006/08/04/467550.html Lua 的语法比较简单,学 ...

随机推荐

  1. js实现滑动拼图验证码

    js实现滑动拼图验证码,我这个样式是仿那些大网站做了, 学习用的,只用到前端. 小的个人网站感觉还可以用,大一点的别人用机器一下就破解了. 下面看图示: 样子大概是这样的. 源码在这 百度网盘:    ...

  2. 《剑指offer》第十五题(二进制中1的个数)

    // 面试题:二进制中1的个数 // 题目:请实现一个函数,输入一个整数,输出该数二进制表示中1的个数.例如 // 把9表示成二进制是1001,有2位是1.因此如果输入9,该函数输出2. #inclu ...

  3. Cocos2dx 3.x 屏幕适配

    Cocos2dx 3.10+Cocos Studio3.10 1.在适配过程中必须明确几个概念: ①Frame大小:这个值在windows/mac/linux下就是创建窗体的大小,在手机上就是屏幕大小 ...

  4. Python 爬虫-BeautifulSoup

    2017-07-26 10:10:11 Beautiful Soup可以解析html 和 xml 格式的文件. Beautiful Soup库是解析.遍历.维护“标签树”的功能库.使用Beautifu ...

  5. 在WPF中添加Windows Form控件(包括 ocx控件)

      首先,需要向项目中的reference添加两个dll,一个是.NET库中的System.Windows.Forms,另外一个是WindowsFormsIntegration,它的位置一般是在C:\ ...

  6. 《图解Http》 10,11章:构建Web的技术, Web的攻击技术

    10.2动态HTML 通过调用客户端脚本语言js,实现对web页面的动态改造.利用DOM文档对象模型,指定想发生变化的元素. 10.22 更容易控制的DOM 使用DOM可以将HTML内的元素当作对象操 ...

  7. windows下apache利用SSL来配置https

    第一步打开httpd.conf文件找到以下两个变量把注释去掉. #LoadModule ssl_module modules/mod_ssl.so (去掉前面的#号) #Include conf/ex ...

  8. python-day39--数据库

    1.什么是数据:描述事物的特征,提取对自己有用的信息  称之为数据 2..什么是数据库: 数据库即存放数据的仓库,只不过这个仓库是在计算机存储设备上,而且数据是按一定的格式存放的 为什么要用数据库: ...

  9. SQL调优(SQL TUNING)之远程支持完成性能大幅优化

    前几天,一个朋友找到我,说一个SQL性能有问题,看看能不能优化,下面为过程: 雪豹 9:35:10 在吗 兰花岛主 15:07:39 忙忘了,有事儿? 雪豹 15:07:49 嗯 雪豹 15:07:5 ...

  10. splunk中mongodb作用——存用户相关数据如会话、搜索结果等

    About the app key value store The app key value store (or KV store) provides a way to save and retri ...