В целом, как преобразовать синтаксис ILASM в рефлексию .emit Callse?

StackOverflow https://stackoverflow.com/questions/3033318

Вопрос

Я пишу мини-компилятор специального назначения, и я часто рассматриваю разборку CIL, чтобы выяснить, как делать вещи. Но часто не очевидно, как перевести разобранный код для размышлений .emit Calls. Существует ли справочное руководство или любой другой источник информации для выполнения этого перевода?

Редактировать: Да, сопоставление Опкоды к ilgenerator, довольно просто; Я говорю обо всех других вещах, таких как. Дейрективы и атрибуты. Например, как вы узнаете, как написать отражение .emit Equivalent что-то вроде Dictionary<TKey,TValue>?

.class public auto ansi serializable beforefieldinit Dictionary<TKey, TValue>
    extends System.Object
    implements System.Collections.Generic.IDictionary`2<!TKey, !TValue>,
    System.Collections.Generic.ICollection`1<valuetype 
        System.Collections.Generic.KeyValuePair`2<!TKey, !TValue>>, 
    ...
{
    .custom instance void System.Diagnostics.DebuggerDisplayAttribute::
        .ctor(string) = { string('Count = {Count}') }

    .method public hidebysig newslot virtual final instance bool TryGetValue
        (!TKey key, [out] !TValue& 'value') cil managed
    {
        .maxstack 3
        .locals init ([0] int32 num)
        ...

Или как насчет директивы «Param»?

// public static void SayHello(string s = "Hello World!")
.method public hidebysig static void SayHello([opt] string s) cil managed
{
    .param [1] = "Hello World!"
Это было полезно?

Решение 3

Поскольку никто не мог ответить на вопрос, я заключаю, никакой документации не существует, чтобы показать взаимосвязь между синтаксисом ILASM и отражением .emit Calls.

В качестве бокового примечания я обнаружил, что обычно лучше создавать код во время выполнения, используя Runsharp. чем отражение .emit. Когда у меня есть время, я постараюсь выяснить новую версию Сесил.

Другие советы

Я бы использовал Компонент эмительпера принадлежащий Bltoolkit. для этой цели. Он обеспечивает беглый API, напоминающий IL-код, оборучающую отражение .emit .emit. Пример, извлеченный из связанного артикула:

EmitHelper emit = new AssemblyBuilderHelper("HelloWorld.dll")
    .DefineType  ("Hello", typeof(object), typeof(IHello))
    .DefineMethod(typeof(IHello).GetMethod("SayHello"))
    .Emitter;
emit
    // string.Format("Hello, {0}!", toWhom)
    //
    .ldstr   ("Hello, {0}!")
    .ldarg_1
    .call    (typeof(string), "Format", typeof(string), typeof(object))

    // Console.WriteLine("Hello, World!");
    //
    .call    (typeof(Console), "WriteLine", typeof(string))
    .ret();

Type type = emit.Method.Type.Create();

Вы смотрите на IL для System.Collections.generic.dictionary <> класс. Название класса «Словарь» - это строка, которую вы передаете в ModuleBuilder.definetype ().

Атрибут .Param генерируется в C # версии 4 или VB.NET для параметров, которые имеют значение по умолчанию. Вы устанавливаете его с ParameterBuiter, вы возвращаетесь из MODICBUILDER.DEFINEPRAMETER (). Используйте метод SetConstant ().

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top