Определение пользовательских атрибутов в Cil

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

  •  26-09-2019
  •  | 
  •  

Вопрос

Что такое синтаксис для определения литерала массива в CIL для целей украшения участника с пользовательским атрибутом?

Я пишу несколько .NET CODE в CIL (используя ILASM.exe, чтобы скомпилировать его), и мне нужно украсить метод с помощью пользовательского атрибута. Конструктор для этого атрибута принимает массив целых чисел в качестве его единственного параметра. Как я могу сделать это в Cil?

Это подпись конструктора пользовательского атрибута (я не могу его изменить):

public FooAttribute(int[] values) {
// some hidden constructor stuff
}

Вот как я бы украсил свой метод, если я пишу в C # (но я не могу):


[Foo(new int[] {1, 2, 3, 4})]
public string Bar() {
  return "Some text";
}

Использование ILDasm.exe, чтобы посмотреть на скомпилированное C # (чтобы попытаться понять по обратным инженерии) дает мне уродливой и непригодный двоичный литерал. Вместо этого я пытался использовать Reflector.net, и он выглядит намного лучше, но Ilasm.exe бросает ошибку синтаксиса по ключевому слову «Новый», поэтому я не могу его использовать:

.custom instance void SomeNamespace.FooAttribute::.ctor(int32[]) = { new int32[int32(4)] { int32(1), int32(2), int32(3), int32(4) } }
Это было полезно?

Решение

Трудно угадать, какова может быть ваша проблема. Если я применю этот атрибут в метод программы .test (), я получу это:

  .method private hidebysig static void  Test() cil managed
  {
    .custom instance void ConsoleApplication1.FooAttribute::.ctor(int32[]) = ( 01 00 04 00 00 00 01 00 00 00 02 00 00 00 03 00 
                                                                               00 00 04 00 00 00 00 00 ) 
    // Code size       2 (0x2)
    .maxstack  8
    IL_0000:  nop
    IL_0001:  ret
  } // end of method Program::Test

Запустите это через Ilasm.exe, нет проблем. Обратите внимание, как значения элемента массива (прокрутите окно фрагмента вправо, чтобы увидеть их) уже преобразуются в формат, необходимый для встраивания их в таблицу данных конструктора атрибута. Bitconverter.getbytes () может получить часть этой работы. Документ ECMA должен иметь необходимый формат этого данных.

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