call valuetype [System.Windows.Forms] System.Windows.Forms.DialogResult [Sуstem.Windоws.Forms] System.Windows.Forms.MessageBox::Show(string, string)

  pop

  ret

 }

}

Хотя здесь объем программного кода CIL заметно больше, чем в случае реализации CILCar, на самом деле все довольно просто. Во-первых, поскольку вы определяете статический метод, вам не придется иметь дел со скрытой объектной ссылкой (поэтому код операции ldarg.0 действительно загружает поступающий аргумент CILCar).

Метод начинается с загрузки строки ("Скорость {0}: ") в стек за которой следует аргумент CILCar. Когда эти два значения оказываются в нужном месте, загружается значение поля petName и вызывается статический метод System.String. Format, чтобы вместо замещающих фигурных скобок получить имя CILCar.

Та же общая процедура выполняется и при обработке поля currSpeed, но следует отметить, что здесь используется код. операции ldarga, которая загружает адрес аргумента в стек. Затем вызывается System.Int32.ToString, чтобы преобразовать значение, размещенное по указанному адресу, в строковый тип. Наконец, когда обе строки отформатированы так, как требуется, вызывается метод MessageBox.Show.

Теперь вы можете скомпилировать свой новый файл *.dll с помощью ilasm.exe, используя команду

ilasm /dll CILCars.il

а затем проверить полученный CIL-код с помощью peverifу.exe.

peverify CILCars.dll

<p>Создание CILCarClient.exe</p>

Теперь нам нужно построить простой компоновочный блок *.exe, который должен выполнить следующее.

• Создать тип CILCar.

• Передать этот тип статическому методу CILCarInfo.Display,

Создайте новый файл *.il и определите внешние ссылки на mscorlib.dll и CILCars.dll (не забудьте поместить копию этого компоновочного блока .NET в каталог приложения клиента!). Затем определите единственный тип (Program), который использует компоновочный блок CILCars.dll. Вот соответствующий программный код, приведенный полностью.

// Ссылки на внешние компоновочные блоки.

.assembly extern mscorlib {

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

 .ver 2:0:0:0

}

.assembly extern CILCars {

 .ver 1:0:0:0

}

// Наш выполняемый компоновочный блок.

.assembly CILCarClient {

 .hash algorithm 0x00008004

 .ver 0:0:0:0

}

.module CILCarClient.exe

// Реализация типа Program.

.namespace CILCarClient {

 .class private auto ansi beforefieldinit Program extends [mscorlib]System.Object {

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

   // Обозначает точку входа *.exe.

   .entrypoint

   .maxstack 8

   // Объявление локального типа CILCar и добавление в стек

   // значений для вызова конструктора.

   .locals init ([0] class [CILCars]CILCars.CILCar myCilCar)

   ldc.i4 55

   ldstr "Junior"

   // Создание нового CILCar: сохранение и загрузка ссылки.

   newobj: instance void [CILCars] CILCars.CILCar::.сtor(int32, string)

   stloc.0

   ldloc.0

   // Вызов Display и передача верхнего значения из стека.

   call void [CILCars] CILCars.CILCarInfo::Display(class [CILCars]CILCars.CILCar)

   ret

  }

 }

}

Здесь единственным кодом операции, заслуживающим комментария, является .entrуpoint. Напомним, что этот код операций используется для обозначения метода, который должен выступать в качестве точки входа модуля *.eхе. Ввиду того, что среда CLR идентифицирует начальный метод для выполнения именно с помощью.entrypoint, сам метод может называться как угодно (хотя в нашем примере он называется Main). В остальном CIL-код метода Main представляет действия, связанные с добавлением значений в стек и извлечением их из стека.

Перейти на страницу:

Похожие книги