如何在Microsoft.NET中使用Mono.CSharp解释器

时间:2011-04-02 00:56:57

标签: c# compiler-construction mono

我认为Mono的编译器是usable in Microsoft.NET

编辑:我最初错过的updated blog posting here解释了其中一些(与贾斯汀的回答一致)

我创建了一个简单的类来尝试使用它

[TestFixture]
class Class1
{
    [Test]
    public void EXPR()
    {
        Evaluator.Run("using System;");

        int sum = (int)Evaluator.Evaluate("1+2");

    }
}

Visual Studio 2010中引用C:\ Program Files(x86)\ Mono-2.10.1 \ lib \ mono \ 4.0 \ Mono.CSharp.dll的项目。

然而,当我尝试运行此任务时,我得到以下异常,抛出Evaluator.Run调用:

    System.TypeInitializationException was unhandled by user code
      Message=The type initializer for 'Mono.CSharp.Evaluator' threw an exception.
      Source=Mono.CSharp
      TypeName=Mono.CSharp.Evaluator
      StackTrace:
           at Mono.CSharp.Evaluator.Run(String statement)
           at Experiments.Class1.EXPR() in W:\Experiments\Class1.cs:line 16
      InnerException: System.TypeLoadException
           Message=Method 'Mono.CSharp.Location.ToString()' is security transparent, but is a member of a security critical type.
           Source=Mono.CSharp
           TypeName=Mono.CSharp.Location.ToString()
           StackTrace:
                at Mono.CSharp.Evaluator..cctor()
           InnerException: 
谷歌确认另一个人问这个问题,但没有答案。我试着开始阅读the microsoft article on security transparent code,但很快就感到困惑。有人能够建议一个快速的解决方法,让我使用它吗?并且可能总结一下安全隐患(如果有的话)(在我的情况下 - 将来我希望用厚客户端应用程序打包它,以便在内部和最终用户使用)

3 个答案:

答案 0 :(得分:6)

last year四月起,它在.NET下工作。

小点,但我注意到你在sum的表达式中缺少一个分号。

int sum = (int)Evaluator.Evaluate("1+2;");

我目前只有Mono 2.11(来自git),他们已经改为使用编译器的多实例版本而不是静态版本。所以,我的代码看起来有点不同:

using System;
using Mono.CSharp;

namespace REPLtest
{
    class MainClass
    {
        public static void Main (string[] args)
        {
            var r = new Report (new ConsoleReportPrinter ());
            var cmd = new CommandLineParser (r);

            var settings = cmd.ParseArguments (args);
            if (settings == null || r.Errors > 0)
                Environment.Exit (1);

            var evaluator = new Evaluator (settings, r);

            evaluator.Run("using System;");

            int sum = (int) evaluator.Evaluate("1+2;");

            Console.WriteLine ("The sum of 1 + 2 is {0}", sum);
        }
    }
}

编辑:我想我应该确认我确实在.NET 4上成功执行了此操作(在Windows XP上使用Visual C#Express 2010)

再次编辑:如果您有Visual Studio,可以download the latest version of Mono.CSharp自行编译。源中包含.sln(解决方案文件),因此您可以在没有Mono的Windows上构建它。生成的程序集将运行上面的代码。 Miguel有一篇文章解释了新的Mono.CSharp here

最终编辑:我上传了我实际使用的here编译的Mono.CSharp.dll程序集。将其作为编译上述代码的参考。

答案 1 :(得分:3)

我觉得我应该让代码更像问题,但我不想覆盖我以前的答案:

下面的代码适用于Mono.CSharp的2.11版(可用here,包括用于使用Visual Studio / .NET构建的解决方案文件)。它在Windows XP上使用.NET 4进行了测试。我目前无法访问Mono 2.10。

[TestFixture]
class Class1
{
    private Evaluator evaluator;

    public Class1()
    {
        var report = new Report(new ConsoleReportPrinter());
        evaluator = new Evaluator(new CompilerSettings(), report);
    }

    [Test]
    public void EXPR()
    {
        evaluator.Run("using System;");

        int sum = (int)evaluator.Evaluate("1+2;");
    }
}

编辑:我上传了我实际使用的here的Mono.CSharp.dll程序集。将其作为编译上述代码的参考。

答案 2 :(得分:3)

看起来这是bug in Mono

.NET 4放弃了Code Access Security但保留了Security Transparent Code的概念。简而言之,执行操作的低级代码(如调用非托管代码)必须是“安全关键”。应用程序级代码标记为“透明”。 “透明”代码无法调用“安全关键”代码。

听起来好像Mono.CSharp.Location.ToString()需要用[SecuritySafeCritical]属性标记,如果你想让Mono 2.10代码与.NET 4一起工作。也许更好的是标记所有的Mono.CSharp为SecuritySafeCritical

http://msdn.microsoft.com/en-us/library/system.security.securitycriticalattribute.aspx

PS。很抱歉,对于一个问题有多个答案。在我意识到2.11会起作用之后,我对2.10的错误意味着什么变得更加好奇。我无法将这个答案与其他答案结合起来。