Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C#5.0应用程序中嵌入lua(或其他脚本语言)_C#_Lua_Dynamic Language Runtime - Fatal编程技术网

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

如何在C#5.0应用程序中嵌入lua(或其他脚本语言),c#,lua,dynamic-language-runtime,C#,Lua,Dynamic Language Runtime,首先,我想提前通知你我的英语水平 我的问题是,我需要在C#应用程序中拥有什么才能解释输入到该应用程序的Lua脚本Lua脚本必须能够访问用C#编写的类。 在搜索stack overflow以获得答案后,我认为有关此主题的问题已经过时(我认为这些问题是在动态语言运行时成为.NET Framework的一部分之前提出的,我认为现在有了DLR,事情就简单多了) 基本上,我想做的是 TypeThatExecutesLua.MethodToLoadLuaScript(script.lua); TypeT

首先,我想提前通知你我的英语水平

我的问题是,我需要在C#应用程序中拥有什么才能解释输入到该应用程序的Lua脚本Lua脚本必须能够访问用C#编写的类。

在搜索stack overflow以获得答案后,我认为有关此主题的问题已经过时(我认为这些问题是在动态语言运行时成为.NET Framework的一部分之前提出的,我认为现在有了DLR,事情就简单多了)

基本上,我想做的是

 TypeThatExecutesLua.MethodToLoadLuaScript(script.lua);
 TypeThatExecutesLua.Execute();
现在,假设我们不关心script.lua返回什么。但在某些情况下,第二行是这样的:

dynamic result = TypeThatExecutesLua.Execute();
int argument
TypeThatExecutesLua.Execute(argument);
或者这个: 动态结果; 键入thatExecutesLua.Execute(输出结果)

类似地,如果可能的话,我希望能够将参数传递给脚本(不确定参数在本例中是否正确,我对脚本知之甚少),如下所示:

dynamic result = TypeThatExecutesLua.Execute();
int argument
TypeThatExecutesLua.Execute(argument);
这可能是一个非常基本的问题,但我真的希望有一个能真正向我解释如何做的答案,而不是一个指向某个页面的链接,因为我缺乏基本知识,无法理解迄今为止通过搜索web找到的大部分材料(我在C#方面相当出色,但这超出了语言本身的范围)

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

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

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基于,它也可以完成所有这一切,但它将更加复杂。

您可以尝试使用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) 如果不希望ActiveState TCL安装在C:\TCL目录下,请删除它

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

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

  //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命令。

您看过NLua()吗?如果是,请参阅的.NET部分中提到的任何其他选项。