热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

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






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 —— 常见报错点









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






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




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



点击 luainterface 链接 ↓↓



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



点击 1.5.3 链接 开始下载



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



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



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



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



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



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



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



并按照步骤添加引用



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



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



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



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





2





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






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



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





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


输出结果:





66
chinar




3





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






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



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





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


输出结果:





666
chianr666




4





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






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



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



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



不会的请看下图



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



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





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



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





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



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





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
你好,Chinar
chinar.fun
nil 10
chinar.fun
8
nil 10




7





All —— 全脚本数据






整个脚本项目



1个C#脚本 2个Lua脚本



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





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")
-- 加载命名空间下的类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文件目录中



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







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




Chinar的GitHub工程案例



直接Down下来运行即可







END





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

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

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







推荐阅读
author-avatar
55525wio
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有