Как вставить CIL-код в C#

Можно ли вставить код IL в метод С#?


person Duiner    schedule 25.07.2010    source источник


Ответы (5)


Я только что выложил утилиту, которая позволяет автоматически заменять целые тела функций C#. со встроенным IL, используя настраиваемый атрибут. Как и аналогичные утилиты, это работает через цикл ILDASM/ILASM, который можно настроить как шаг после сборки. Инструмент также настраивает PDB, чтобы сохранить пошаговое выполнение и установку точек останова для отдельных инструкций IL в отладчике. Он отличается от некоторых других встроенных IL-инлайнеров в оба конца тем, что он (только) заменяет целые тела функций, например:

    class MyClass
    {
        [ILFunc(@"
    .locals init ([0] int32 i_arg)
        ldc.i4.3
        ret
    ")]
        int MyFunc(int i_arg)
        {
            return 3;
        }
    };

Для высококритичных к производительности методов я попытался использовать DynamicMethod для улучшения генерируемого компилятором IL, но обнаружил, что преимущество теряется из-за накладных расходов, связанных с вызовом делегата. Встроенный IL дает преимущество ручной настройки IL без этого удара, при условии, что нет настроек времени выполнения, для которых вам действительно понадобится DynamicMethod.

Полный исходный код находится по адресу http://www.glennslayden.com/code/c-sharp/inline-il

person Glenn Slayden    schedule 10.05.2011
comment
Не нашел атрибута ILFunc в вашей библиотеке. - person Denis; 14.08.2016
comment
@ Денис Я не думаю, что предоставлял библиотеку. Это исходный код, и на веб-странице есть два файла. Второй (прокрутите вниз за дополнительный текст) содержит определение самого ILFunc Attribute. - person Glenn Slayden; 02.02.2017

Если вам нужен встроенный IL (в духе встроенного ассемблера, поддерживаемого компиляторами C и C++), этого можно добиться с помощью циклической компиляции после компиляции.

Майк Столл однажды написал инструмент для этого, насколько я знаю, он довольно зрелый:

Кроме этого, вы можете использовать F#, который поддерживает Inline IL.

person Johannes Rudolph    schedule 25.07.2010
comment
Вы знаете, где найти инструмент Майка Столла? Ссылка не работает. Спасибо! - person raff; 09.05.2020

DynamicMethod — это упрощенный способ выполнить это. во время выполнения.

Компилятор Microsoft C# не поддерживает внедрение IL во время компиляции, но инструмент объединения кода может сделать это на этапе после компиляции.

person Ben Voigt    schedule 25.07.2010

Я добавлю свой собственный инструмент в список уже представленных здесь решений: InlineIL.Fody.

При этом используется инструмент создания сборки Fody для изменения сборки во время сборки. Это означает, что все, что вам нужно сделать, это установить пакет NuGet, добавить файл конфигурации в свой проект, и все готово.

Затем вам предоставляется простой и типобезопасный API для генерации инструкций IL, которые вы можете смешивать с кодом C#. Я считаю, что таким способом писать IL проще, чем писать текст, и это также удобнее, чем ILGenerator, поскольку каждый опкод получает свой собственный метод только с соответствующими перегрузками.

Вот пример с using static InlineIL.IL.Emit;:

public static void ZeroInit<T>(ref T value)
    where T : struct
{
    Ldarg(nameof(value));
    Ldc_I4_0();
    Sizeof(typeof(T));
    Unaligned(1);
    Initblk();
}

Здесь показано, как получить доступ к initblk инструкция, которую C# в настоящее время не предоставляет.

person Lucas Trzesniewski    schedule 09.09.2018
comment
Вау, я не знал такого замечательного расширения! Это прекрасно работает! Мне кажется, что встроенный IL :) - person raff; 09.05.2020

Инструмент, который вам нужен, называется Cecil и является частью проекта Mono.

Вы можете получить больше информации об этом здесь: http://www.mono-project.com/Cecil

Цитата с сайта выше:

Cecil — это библиотека, написанная Jb Evain (http://evain.net/blog/) для создания и проверять программы и библиотеки в формате ECMA CIL. Он имеет полную поддержку дженериков и поддерживает некоторые форматы символов отладки.

Говоря простым английским языком, с помощью Cecil вы можете загружать существующие управляемые сборки, просматривать все содержащиеся в них типы, модифицировать их на лету и сохранять измененную сборку обратно на диск.

person Community    schedule 25.07.2010