Моно компилятор как услуга (MCS)

Я хотел бы использовать компилятор Mono как услуга от моей регулярной.NET 3,5 приложения.

Я загрузил последние биты (2.6.7), создал простое консольное приложение в Visual Studio и сослался на Моно. До-диез 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. Выполненный (первая строка):

Illegal enum value: 2049.
Parameter name: access

Это вызвано тем, что dll был скомпилирован с помощью Mono.exe, не csc.exe, я верю.

Я попытался загрузить Моно. До-диез dll непосредственно из http://tirania.org/blog/archive/2010/Apr-27.html в файле demo-repl.zip... и это не выдает исключение... Однако параметр (res) после называния Средства анализа. Оцените является пустым..., таким образом, я не уверен, что идет не так, как надо. Никакое исключение не выдается...

Так, я хотел бы выяснить, почему dll я загрузил с пустого указателя возвратов demo-repl.zip.

Править: Я выяснил, почему это возвращает пустой указатель. Кажется по некоторым причинам, что компилятор не берет Систему. Пространство имен Linq..., хотя я не могу сказать почему... Если я просто Оцениваю "Систему. IO.Directory. GetFiles (\"C:\\")", это хорошо работает.

ОБНОВЛЕНИЕ: определенно кажется, что существует что-то не так с Моно компилятором, берущим Системные блоки, на которые ссылаются. Если я непосредственно копирую образец их консольного инструмента до-диеза:

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). У кого-либо есть идея того, насколько трудный это будет, или кто-либо может указать на меня в правильном направлении здесь?

Спасибо.

8
задан Jeff 4 August 2010 в 21:40
поделиться

2 ответа

Хорошо, думаю, у меня есть несколько ответов.

Чтобы решить проблему с загрузкой сборки, я могу либо вызвать Assembly.LoadWithPartialName внутри Mono.CSharp.Driver.LoadAssembly, либо сделать следующее в моем приложении

        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 / Вызов компиляции, все, что мне нужно было изменить, это следующее (хотя, вероятно, мне здесь не хватает некоторых сложностей) .....

Внутри 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; }

Затем .. . убедитесь, что Reset вызывается хотя бы один раз в Init:

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

И, наконец, в ParseString, просто не сбрасывайте, если AutoReset не истинно ...

        static CSharpParser ParseString (ParseMode mode, string input, out bool partial_input)
        {
.
.
.
            if (AutoReset) Reset ();
2
ответ дан 6 December 2019 в 00:54
поделиться

Согласно странице блога Мигеля, которую вы связали, вы должны добавить ссылку на System.Core, чтобы использовать LINQ в .Net.

csharp> using System.Linq;
csharp> from x in "Foo" select x;
1
ответ дан 6 December 2019 в 00:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: