Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Троелсен Э. Язык программирования С# 2010 и п...docx
Скачиваний:
113
Добавлен:
21.09.2019
Размер:
6.92 Mб
Скачать

Роль меток в программном коде cil

Вы. конечно, заметили, что в каждой строке программного кода реализации содержится префикс в форме лексемы IL_XXX: (например, IL_0000: IL_0001: и т.д.). Эти лексемы называются метками кода, и они могут иметь любой вид, какой вы только пожелаете (лишь бы они не дублировались в пределах одного и того же контекста). При записи содержимого компоновочного блока в файл с помощью ildasm.exe автоматически генерируются метки кода, имеющие вид IL_XXX:. Но вы можете изменить их с тем, чтобы они стали более информативными.

.method private hidebysig static void Main(string[] args) cil managed {

 .entrypoint

 .maxstack 8

 Nothing_1: nop

 Load_String: ldstr "Hello CIL code!"

 PrintToConsole: call void [mscorlib]System.Console::WriteLine(string)

 Nothing_2: nop

 WaitFor_KeyPress: call string [mscorlib] System.Console::ReadLine()

 RemoveValueFromStack: pop

 Leave_Functlon: ret

}

Суть в том, что большинство меток кода совсем необязательно. Единственным случаем, когда метки кода оказываются по-настоящему полезными (и обязательными), является случай, когда в программном коде CIL используются ветвления или циклические конструкции. Например, в нашем случае вы можете исключить метки вообще.

.method private hidebysig static void Main(string[] args) cil managed {

 .entrypoint

 .maxstack 8

 nop

 ldstr "Hello CIL code!"

 call void [mscorlib]System.Console::WriteLine(string)

 nop

 call string [mscorlib]System.Console::ReadLine()

 pop

 ret

}

Взаимодействие с cil: модификация файла *.Il

Теперь, когда вы понимаете, как компонуется базовый файл CIL, давайте завершим наш эксперимент с челночной технологией разработки программ. С помощью изменения CIL-кода в файле *.il мы должны выполнить следующее.

• Добавить ссылку на компоновочный блок System.Windows.Forms.dll.

• Загрузить локальную строку в Main().

• Вызвать метод System.Windows.Forms.MessageBox.Show(), используя локальную строковую переменную в качестве его аргумента.

Первым шагом является добавление новой директивы.assembly (с атрибутом extern), которая укажет, что используется System.Windows.Forms.dll. Для этого просто добавьте в файл *.il следующую программную логику после ссылки на внешний компоновочный блок mscorlib.

.assembly extern System.Windows.Forms {

 .publickeytoken = (B7 7A 5C 56 19 34 E0 89)

 .ver 2:0:0:0

}

Значение, указанное директивой .ver. может у вас оказаться другим, поскольку оно зависит от версии платформы .NET, установленной на вашей машине. Здесь указано использование System.Windows.Forms.dll версии 2.0.0.0 с кодом открытого ключа В77А5С561934Е089. Если открыть GAC (см. главу 11) и найти там компоновочный блок System.Windows.Forms.dll, можно скопировать правильный номер версии и значение открытого ключа со страницы свойств этого компоновочного блока.

.method private hidebysig static void Main(string[] args) cil managed {

 .entrypoint

 .maxstack 8

 // Задача: написать новый CIL-код.

}

Итак, целью является помещение новой строки в стек и вызов метода MessageBox.Show() (а не метода Console.WriteLine()). Напомним, что при указании имени внешнего типа следует использовать абсолютное имя типа (в совокупности с понятным именем компоновочного блока). С учетом этого обновите метод Main() так, как показано ниже.

.method private hidebysig static void Main(string[] args) cil managed {

 .entrypoint

 .maxstack 8

 ldstr "CIL работает прекрасно!"

 call valuetype [System.Windows.Forms] System.Windows.Forms.DialogResult [System.Windows.Forms] System.Windows.Forms.MessageBox::Show(string)

 pop

 ret

}

В результате вы получите программный код CIL, соответствующий следующему определению класса C#.

public class Program {

 static void Main(string[] args) {

  System.Windows.Forms.MessageBox.Show("CIL работает прекрасно!");

 }

}