如何在 C# 5.0 应用程序中嵌入 lua (或其他脚本语言)

首先,我想提前为我的英语道歉。

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

在搜索了 stack overflow 的答案后,我认为涉及此主题的问题已经过时了(我认为它们是在动态语言运行时成为 .NET Framework 的一部分之前提出的,我认为现在可能更简单了,因为我们有了 DLR)。

基本上,我想要做的是这样的:

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

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

dynamic result = TypeThatExecutesLua.Execute();

或者是这样的: dynamic result; TypeThatExecutesLua.Execute(out result);

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

int argument
TypeThatExecutesLua.Execute(argument);

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

最后,我想说的是,即使 Lua 是我的目标语言,如果解决方案类似或相同于任何语言,只有区别于要在项目中下载和引用哪些 Dll 和 Dll 本身的界面等细节,我想知道。

点赞
用户98917
用户98917

看起来 DynamicLua (GitHub, NuGet 软件包) 有你想要的:

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,它也可以做所有这些,但会更加复杂。

2014-03-08 18:40:30
用户5632412
用户5632412

你可以尝试使用 TCL,这是嵌入式脚本的祖先:

(1)下载并安装 ActiveState TCL。

(2)将文件C:\ Tcl \ bin \ tcl86.dll和C:\ Tcl \ bin \ zlib1.dll复制到您的C# exe所在的位置,最可能位于“Debug”目录下。 (注意:86版本号可能需要调整为您下载的TCL的实际版本)您还可以将tcl86.dll复制到系统路径所在的目录中。但是,当您想要从计算机移动应用程序时,这会有些混淆,因为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命令。

2017-03-09 15:28:09