如何在C#中集成Lua脚本
背景
在很多时候我们代码中的一些逻辑操作并不能够硬编码到代码中,我们可能希望通过配置来完成这个操作,所以这个时候我们就需要有一些脚本语言能够处理这些操作,在C#语言中比较常见的就是通过引入NLua这个动态库来引入lua脚本语言从而达到灵活配置的目的,这篇文章主要是通过具体的实例来说明在C#中如何通过引入NLua并调用配置的脚本。
步骤
1引入NLua.dll
这个dll是一个很轻量级的库,100kb左右,引用这个库可以通过Nuget包管理器来引用,当前引用的版本是1.5.7.0,我们看看引用之后的添加了哪些DLL。
这个里面lua54.dll有x86和x64两个类型的版本,这个在使用的时候需要注意因为我们生成设置选择的是AnyCPU所以这里会有两个版本的dll,这里使用的时候需要注意。
2具体用法
下面通过一个控制台应用程序来看看这个脚本到底该怎么使用,这里包括直接创建表达式,注册方法并使用lua调用C#函数以及直接导入C#的库然后再调用里面内部的方法这三个方面进行描述。
2.1 直接创建表达式
我们来直接看控制台程序中的代码
classProgram { staticvoidMain(string[]args) { using(varstate=newLua()) { //Evaluatingsimpleexpressions: //Luacanreturnmultiplevalues,forthisreasonDoStringreturnaarrayofobjects varres0=state.DoString("return10+3*(5+2)")[0]; Console.WriteLine($"Outputresult0:{res0}"); //Passingrawvaluestothestate: doubleval=12.0; state["x"]=val;//Createaglobalvalue'x' varres1=(double)state.DoString("return10+x*(5+2)")[0]; Console.WriteLine($"Outputresult1:{res1}"); //Retrievingglobalvalues: state.DoString("y=10+x*(5+2)"); doubley=(double)state["y"];//Retrievethevalueofy Console.WriteLine($"Yresult:{y}"); Console.ReadKey(); } }}
注意事项:
首先来看这个注释:Luacanreturnmultiplevalues,forthisreasonDoStringreturnaarrayofobjects,就是直接调用DoString方法的时候返回的结果是一个object[]类型,所以这里需要取结果的时候要取用第一个
2.2注册LuaFunction
这里我们通过直接在DoString中定义好function,然后通过Call方法进行调用,我们再来看下面的示例及返回结果
classProgram { staticvoidMain(string[]args) { using(varstate=newLua()) { //RetrievingLuafunctions: state.DoString(@"functionScriptFunc(val1,val2) ifval1>val2then returnval1+1 else returnval2-1 end end "); varscriptFunc=state["ScriptFunc"]asLuaFunction; varfuncRes=scriptFunc.Call(3,5).First(); Console.WriteLine($"Funcresult:{funcRes}"); Console.ReadKey(); } } }
同样的我们也来看看最终执行的结果
2.3Lua调用C#函数
下面的例子包含了几种不同的参数类型及返回类型用来演示调用的完整过程。
usingSystem; usingSystem.Linq; usingNLua; namespaceNLuaConsoleApp { classProgram { staticvoidMain(string[]args) { using(varstate=newLua()) { ////---------------------------------------------------lua调用c#函数 TestClassobj=newTestClass(); //注册CLR对象方法到Lua,供Lua调用typeof(TestClass).GetMethod("TestPrint") state.RegisterFunction("TestPrint",obj,obj.GetType().GetMethod("TestPrint")); //注册CLR对象方法到Lua,供Lua调用typeof(TestClass).GetMethod("AnotherFunc") state.RegisterFunction("AnotherFunc",obj,obj.GetType().GetMethod("AnotherFunc")); //注册CLR静态方法到Lua,供Lua调用 state.RegisterFunction("TestStaticPrint",null,typeof(TestClass).GetMethod("TestStaticPrint")); state.DoString("TestPrint(10,20)"); state.DoString("AnotherFunc('10','20')"); state.DoString("TestStaticPrint()"); Console.ReadKey(); } } classTestClass { publicintTestPrint(intnum,intnum2) { varresult=num+num2; Console.WriteLine("Printresult:"+result); returnresult; } publicvoidAnotherFunc(stringval1,stringval2) { Console.WriteLine($"MyTest,Param1:{val1},Param2:{val2}"); } publicstaticvoidTestStaticPrint() { Console.WriteLine("TestStaticPrint"); } } } }
同样的我们来看整个测试的返回完整结果。
2.4通过Import导入命名空间引用C#函数
这个是按照官方的例子进行模拟的,但是在调用的时候总是报错,现贴出具体的示例供后面排查使用
classProgram { staticvoidMain(string[]args) { using(varstate=newLua()) { state.LoadCLRPackage(); state.DoString(@"import('System.Web')"); state.DoString(@"client=WebClient()"); state.DoString(@"localres=client:DownloadString('http://nlua.org')"); Console.ReadKey(); } } }
这个就是说通过调用C#程序集并引入命名空间,然后调用其内部的WebClient方法,这个在调试的时候一直都是报错,这个暂时记录供以后进行排查错误
3总结
这里有一些地方需要注意Lua对象是实现了IDispose接口的,所以我们在使用的时候需要注意使用using方式或者是使用后调用Dispose方法来对资源进行释放。另外C#中引入Lua脚本的常见主要是适用于部分调用过程不适合硬编码在代码里而适合放在配置中,通过配置不同的Lua脚本从而对程序进行定制化操作,是对现有代码一个很好的补充,另外对于调用C#中dll的方法出现的问题还在研究中,后面发现了再更新此过程。
以上就是如何在C#中集成Lua脚本的详细内容,更多关于C#中集成Lua脚本的资料请关注毛票票其它相关文章!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。