簡體   English   中英

Mono編譯器即服務(MCS)

[英]Mono Compiler as a Service (MCS)

我想將Mono的編譯器作為我的常規.NET 3.5應用程序中的一項服務使用。

我下載了最新版本(2.6.7),在Visual Studio中創建了一個簡單的控制台應用程序,並引用了Mono.CSharp dll。

然后,在我的控制台應用程序中(直接在線獲取示例):

    Evaluator.Run("using System; using System.Linq;");
    bool ress;
    object res;
    Evaluator.Evaluate(
         "from x in System.IO.Directory.GetFiles (\"C:\\\") select x;",
         out res, out ress);

    foreach (var v in (IEnumerable)res)
    {
        Console.Write(v);
        Console.Write(' ');
    }

這會在Evaluator.Run(第一行)處引發異常:

Illegal enum value: 2049.
Parameter name: access

我相信這是因為dll是使用Mono.exe而不是csc.exe編譯的。

我嘗試直接從demo-repl.zip文件中的http://tirania.org/blog/archive/2010/Apr-27.html下載Mono.CSharp dll ...這不會引發異常。 ..但是,調用Evaluator.Evaluate之后的out參數(res)為null ...所以我不確定出了什么問題。 沒有異常被拋出...

因此,我想弄清楚為什么我從demo-repl.zip下載的dll返回null。

編輯:我想通了為什么它返回null。 似乎出於某種原因,編譯器沒有選擇System.Linq命名空間...雖然我無法告訴原因...如果我只是評估“ System.IO.Directory.GetFiles(\\” C:\\\\ “)”,效果很好。

更新:絕對似乎Mono編譯器選擇了引用的System程序集存在問題。 如果我直接復制其csharp控制台工具的示例:

csharp> var list = new int [] {1,2,3};
csharp> var b = from x in list
   >    where x > 1
   >    select x;
csharp> b;

我得到例外:

{interactive}(1,25): error CS1935: An implementation of `Select' query expressio
n pattern could not be found. Are you missing `System.Linq' using directive or `
System.Core.dll' assembly reference?

另外,為了使MCS實際上是一個可行的解決方案,我需要修改編譯器,以便將其發出給單個動態程序集,而不是每個評估調用都發出一個程序集(否則,它將產生大量的內存泄漏,這將導致大量內存泄漏)我以前以CSharpCodeProvider的形式進行過處理。 有誰知道這將有多困難,或者有人可以在這里向我指出正確的方向?

謝謝。

好吧,我想我有一些答案。

要解決程序集加載問題,我可以在Mono.CSharp.Driver.LoadAssembly中調用Assembly.LoadWithPartialName,或者在我的應用程序中執行以下操作

        AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);

        private static bool isResolving;
        static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            if (!isResolving)
            {
                isResolving = true;
                var a = Assembly.LoadWithPartialName(args.Name);
                isResolving = false;
                return a;
            }
            return null;
        }

為了使Mono在每個Evaluate / Compile調用中重用相同的動態程序集,我要做的就是以下更改(盡管我可能在這里缺少復雜性).....

在Mono.CSharp.Evaluator中,我添加了屬性:

/// <summary>
/// Gets or sets a value indicating whether to auto reset when evaluations are performed and create a new assembly.
/// </summary>
/// <value><c>true</c> if [auto reset]; otherwise, <c>false</c>.</value>
public static bool AutoReset { get; set; }

然后...確保在Init中至少調用一次Reset:

    static void Init ()
    {
        Init (new string [0]);
        Reset();
    }

最后,在ParseString中,除非AutoReset為true,否則不要重置...

        static CSharpParser ParseString (ParseMode mode, string input, out bool partial_input)
        {
.
.
.
            if (AutoReset) Reset ();

根據您鏈接的Miguel的博客頁面,您必須添加對System.Core的引用,才能在.Net上使用LINQ。

csharp> using System.Linq;
csharp> from x in "Foo" select x;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM