【问题标题】:How to embed lua (or some other scripting language) in a C# 5.0 application如何在 C# 5.0 应用程序中嵌入 lua(或其他脚本语言)
【发布时间】:2014-04-11 15:26:14
【问题描述】:

首先,我想提前申请我的英语。

我的问题特别是关于我需要在 C# 应用程序中拥有什么才能解释提供给所述应用程序的 Lua 脚本。 Lua 脚本必须能够访问用 C# 编写的类。

在搜索堆栈溢出以寻找答案后,我认为处理该主题的问题已经过时(我认为在动态语言运行时成为 .NET 框架的一部分之前就提出了这些问题,我认为现在事情会变得更简单我们有 DLR)。

基本上,我想做的就是这个

 TypeThatExecutesLua.MethodToLoadLuaScript(script.lua);
 TypeThatExecutesLua.Execute();

现在,假设我们不在乎 script.lua 返回什么。但是在某些情况下,第二行会是这样的:

dynamic result = TypeThatExecutesLua.Execute();

或者这个: 动态结果; TypeThatExecutesLua.Execute(输出结果);

同样,如果可能的话,我希望能够将参数传递给脚本(不确定在这种情况下参数是否是正确的词,我对脚本知之甚少),如下所示:

int argument
TypeThatExecutesLua.Execute(argument);

这可能是一个非常基本的问题,但我非常感谢能真正向我解释如何做到这一点的答案,而不是指向某个页面的链接,因为我缺乏理解大部分材料的基本知识到目前为止,我是通过网络搜索发现的(我相当擅长 C#,但这超出了语言本身的范围)。

最后一点,我想说的是,即使 Lua 是我的目标语言,如果解决方案与任何语言相似或相同,只是在项目中下载和引用哪个 dll 以及dll本身的接口,我想知道。

【问题讨论】:

标签: c# lua dynamic-language-runtime


【解决方案1】:

看起来 DynamicLua (GitHub, NuGet Package) 有你想要的:

dynamic lua = new DynamicLua.DynamicLua();
lua("print('hello world')"); // => hello world
double answer = lua("return 42"); 
Console.WriteLine(answer); // => 42
var arg = 5;
lua("function luafunction(a) return a + 1 end");
dynamic answer2 = lua.luafunction(arg);
Console.WriteLine(answer2); // => 6

Console.ReadKey();

DynamicLua 基于NLua,它也可以做到这一切,但会更复杂。

【讨论】:

    【解决方案2】:

    您可以尝试使用嵌入式脚本之父 TCL:

    (1) 下载 ActiveState TCL 并安装。

    (2) 将文件 C:\Tcl\bin\tcl86.dll 和 C:\Tcl\bin\zlib1.dll 复制到您的应用程序的 C# exe 所在的位置,很可能在“调试”目录下。 (注:86版本号可能需要调整为您下载的实际TCL版本)您也可以将tcl86.dll复制到您的SYSTEM路径的目录中。但是,当您想从计算机中移动应用程序并且由于缺少 tcl86.dll 而无法工作时,这有点令人困惑。

    (3) 如果您不想在 C:\Tcl 目录下安装 ActiveState TCL,请删除它。

    (3) 创建一个 C# 控制台应用程序。将项目编译属性标志设置为“不安全”代码。 (因为 tcl86.dll 在其结果返回接口中使用了 char* 指针。)

    (4) 将以下内容剪切并粘贴到您的 c# 控制台项目中:

      //FILE: program.cs
      using System;
    
      namespace tcl1
      {
       class Program
       {
         public static void Main(string[] args)
         {
           Console.WriteLine("Hello World!");
    
           TclInterpreter interp = new TclInterpreter();
    
           //rc == 0 means OK           
           int rc = interp.evalScript("set a 3; expr {$a + 2}");
           Console.WriteLine("rc=" + rc.ToString() 
                                + " Interp.Result = " + interp.Result);
    
           Console.Write("Press any key to continue . . . ");
           Console.ReadKey(true);
         }//main
       } //class
     }//namespace
    
      //File: tcl_api.cs
      using System.Runtime.InteropServices;
      using System;
    
      namespace tcl1 {
        public class TclAPI {
             [DllImport("tcl86.dLL")]
             public static extern IntPtr Tcl_CreateInterp();
    
             [DllImport("tcl86.dll")]
             public static extern int Tcl_Eval(IntPtr interp,string skript);
    
             [DllImport("tcl86.dll")]
             public static extern IntPtr Tcl_GetObjResult(IntPtr interp);
    
             [DllImport("tcl86.dll")]
             unsafe public static extern char* 
               Tcl_GetStringFromObj(IntPtr tclObj,IntPtr length);
        }
    
        public class TclInterpreter {
            private IntPtr interp;
    
            public TclInterpreter() {
                interp = TclAPI.Tcl_CreateInterp();
                if (interp == IntPtr.Zero) {
                    throw new SystemException("can not initialize Tcl interpreter");
                }
            }
    
            public int evalScript(string script) {
                return TclAPI.Tcl_Eval(interp,script);        
            }
    
            unsafe public string Result {
                get { 
                    IntPtr obj = TclAPI.Tcl_GetObjResult(interp);
                    if (obj == IntPtr.Zero) {
                        return "";
                    } else {
                        return Marshal.PtrToStringAnsi((IntPtr)
                         TclAPI.Tcl_GetStringFromObj(obj,IntPtr.Zero));
                    }
                }
            }
    
        }  
      }
    

    另外,如果您需要评估 TCL 脚本,请在 eval 中使用“source”TCL 命令。

    【讨论】:

      猜你喜欢
      • 2010-10-07
      • 2010-10-02
      • 1970-01-01
      • 1970-01-01
      • 2012-04-12
      • 1970-01-01
      • 1970-01-01
      • 2011-02-11
      • 1970-01-01
      相关资源
      最近更新 更多