ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

C#中集成Lua脚本

2021-02-25 10:02:45  阅读:112  来源: 互联网

标签:集成 调用 DoString C# Lua state Console


背景

  在很多时候我们代码中的一些逻辑操作并不能够硬编码到代码中,我们可能希望通过配置来完成这个操作,所以这个时候我们就需要有一些脚本语言能够处理这些操作,在C#语言中比较常见的就是通过引入NLua这个动态库来引入lua脚本语言从而达到灵活配置的目的,这篇文章主要是通过具体的实例来说明在C#中如何通过引入NLua并调用配置的脚本。

步骤

1 引入NLua.dll

  这个dll是一个很轻量级的库,100kb左右,引用这个库可以通过Nuget包管理器来引用,当前引用的版本是1.5.7.0,我们看看引用之后的添加了哪些DLL。

图一 NLua包

 这个里面lua54.dll有x86和x64两个类型的版本,这个在使用的时候需要注意因为我们生成设置选择的是Any CPU所以这里会有两个版本的dll,这里使用的时候需要注意。

2 具体用法

  下面通过一个控制台应用程序来看看这个脚本到底该怎么使用,这里包括直接创建表达式,注册方法并使用lua调用C#函数以及直接导入C#的库然后再调用里面内部的方法这三个方面进行描述。

  2.1 直接创建表达式

       我们来直接看控制台程序中的代码

 class Program
    {
        static void Main(string[] args)
        {
            using (var state = new Lua())
            {
                //Evaluating simple expressions:
                //Lua can return multiple values, for this reason DoString return a array of objects
                var res0 = state.DoString("return 10 + 3*(5 + 2)")[0];
                Console.WriteLine($"Output result0:{res0}");

                //Passing raw values to the state:
                double val = 12.0;
                state["x"] = val; // Create a global value 'x' 
                var res1 = (double)state.DoString("return 10 + x*(5 + 2)")[0];
                Console.WriteLine($"Output result1:{res1}");

                //Retrieving global values:
                state.DoString("y = 10 + x*(5 + 2)");
                double y = (double)state["y"]; // Retrieve the value of y
                Console.WriteLine($"Y result:{y}");                
              
                Console.ReadKey();
            }
        }
}

 图二 生成结果

  注意事项:

  首先来看这个注释:Lua can return multiple values, for this reason DoString return a array of objects,就是直接调用DoString方法的时候返回的结果是一个object[]类型,所以这里需要取结果的时候要取用第一个 

 

图三  DoString生成结果

  2.2 注册Lua Function

  这里我们通过直接在DoString中定义好function,然后通过Call方法进行调用,我们再来看下面的示例及返回结果

    class Program
    {
        static void Main(string[] args)
        {
            using (var state = new Lua())
            {
                //Retrieving Lua functions:
                state.DoString(@"function ScriptFunc (val1, val2)
                                            if val1 > val2 then
                                                return val1 + 1
                                            else
                                                return val2 - 1
                                            end
                                        end
                                        ");
                var scriptFunc = state["ScriptFunc"] as LuaFunction;
                var funcRes = scriptFunc.Call(3, 5).First();
                Console.WriteLine($"Func result:{funcRes}");

                Console.ReadKey();
            }
        }
}

  同样的我们也来看看最终执行的结果

图四  Func.Call生成结果

  2.3 Lua调用C#函数

  下面的例子包含了几种不同的参数类型及返回类型用来演示调用的完整过程。

using System;
using System.Linq;
using NLua;

namespace NLuaConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var state = new Lua())
            {
                ////---------------------------------------------------lua调用c#函数
                TestClass obj = new TestClass();

                // 注册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();
            }
        }

        class TestClass
        {

            public int TestPrint(int num,int num2)
            {
                var result = num + num2;
                Console.WriteLine("Print result:" + result);
                return result;
            }

            public void AnotherFunc(string val1, string val2)
            {
                Console.WriteLine($"MyTest,Param1:{val1},Param2:{val2}");
            }

            public static void TestStaticPrint()
            {
                Console.WriteLine("TestStaticPrint");
            }
        }

    }
}

  同样的我们来看整个测试的返回完整结果。

 

图五 Lua调用C#函数返回结果

  2.4 通过Import导入命名空间引用C#函数

  这个是按照官方的例子进行模拟的,但是在调用的时候总是报错,现贴出具体的示例供后面排查使用

class Program
    {
        static void Main(string[] args)
        {
            using (var state = new Lua())
            {
                state.LoadCLRPackage();
                state.DoString(@" import ('System.Web') ");
                state.DoString(@" client = WebClient() ");
                state.DoString(@"local res = client:DownloadString('http://nlua.org')");

                Console.ReadKey();
            }
        }
    }

  这个就是说通过调用C#程序集并引入命名空间,然后调用其内部的WebClient方法,这个在调试的时候一直都是报错

 

 

图六 Lua调用C#函数调用错误

 

标签:集成,调用,DoString,C#,Lua,state,Console
来源: https://www.cnblogs.com/seekdream/p/14431273.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有