Создайте новый файл *.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, сам метод может называться
Заметьте, однако, что для создания CILCar используется код операции.newobj. В связи с этим напомним, что при вызове члена типа непосредственно в CIL вы должны применить синтаксис с использованием двойного двоеточия и, как всегда, указать абсолютное имя типа. Восприняв сказанное, вы можете скомпилировать свой новый файл с помощью ilasm.exe, проверить полученный компоновочный блок с помощью peverifу.exe, а затем выполнить программу.
ilasm CilCarClient.il
peverify CilCarClient.exe
CILCarClient.exe
На рис. 15.5 показан конечный результат.
Рис. 15.5. Ваш CILCar в действии
На этом, выполнив первую задачу этой главы, мы закончим освоение азбуки CIL. К этому моменту, я надеюсь, вы уверенно сможете открыть любой компоновочный блок .NET с помощью ildasm.exe и лучше понимаете, что происходит внутри него.
Динамические компоновочные блоки
Как видите, процесс создания сложного приложения .NET непосредственно в CIL оказывается довольно трудоемким. С одной стороны, CIL является чрезвычайно выразительным языком программирования, позволяющим взаимодействовать со всеми программными конструкциями, допустимыми в CTS. С другой стороны, создание CIL-кода является делом скучным, утомительным и сопряженным с множеством ошибок. Хотя верно и то, что знание – это сила, вы можете поинтересоваться, действительно ли это так важно, чтобы "загромождать" законами синтаксиса CIL свою память. Я отвечу так: это зависит от многого. Конечно, для большинства ваших .NET-проектов рассматривать, редактировать или непосредственно создавать программный код CIL не потребуется. Но, освоив азбуку CIL, вы теперь готовы к обсуждению динамических компоновочных блоков (которые называются так в противоположность статическим компоновочным блокам) и роли пространства имен System.Reflection.Emit.