Рейтинговые книги
Читем онлайн Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 345 346 347 348 349 350 351 352 353 ... 642

   IL_0011:  ret

 } // end of method '<Program>$'::'<Main>$'

Роль меток в коде CIL

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

.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 [System.Console]System.Console::WriteLine(string)

  Nothing_2: nop

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

  RemoveValueFromStack: pop

  Leave_Function: ret

}

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

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

{

  .entrypoint

  .maxstack 8

  nop

  ldstr "Hello CIL code!"

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

  nop

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

  pop

  ret

}

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

Теперь, когда вы имеете представление о том, из чего состоит базовый файл CIL, давайте завершим эксперимент с возвратным проектированием. Цель здесь довольно проста: изменить сообщение, которое выводится в окно консоли. Вы можете делать что-то большее, скажем, добавлять ссылки на сборки или создавать новые классы и методы, но мы ограничимся простым примером.

Чтобы внести изменение, вам понадобится модифицировать текущую реализацию операторов верхнего уровня, созданную в виде метода <Main>$(). Отыщите этот метод в файле *.il и измените сообщение на "Hello from altered CIL code!".

(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})

Фактически код CIL был модифицирован для соответствия следующему определению на языке С#:

static void Main(string[] args)

{

  Console.WriteLine("Hello from altered CIL code!");

  Console.ReadLine();

}

Компиляция кода CIL

Предшествующие версии .NET позволяли компилировать файлы *.il с применением утилиты ilasm.exe. В .NET Core положение дел изменилось. Для компиляции файлов *.il вы должны использовать тип проекта Microsoft.NET.Sdk.IL. На момент написания главы он все еще не был частью стандартного комплекта SDK.

Начните с создания нового каталога на своей машине. Создайте в этом каталоге файл global.json, который применяется к текущему каталогу и всем его подкаталогам. Он используется для определения версии комплекта SDK, которая будет задействована при запуске команд .NET Core CLI. Модифицируйте содержимое файла, как показано ниже:

{

  "msbuild-sdks": {

    "Microsoft.NET.Sdk.IL": "5.0.0-preview.1.20120.5"

  }

}

На следующем шаге создается файл проекта. Создайте файл по имени RoundTrip.ilproj и приведите его содержимое к следующему виду:

<Project Sdk="Microsoft.NET.Sdk.IL">

  <PropertyGroup>

    <OutputType>Exe</OutputType>

    <TargetFramework>net5.0</TargetFramework>

     <MicrosoftNetCoreIlasmPackageVersion>

        5.0.0-preview.1.20120.5

     </MicrosoftNetCoreIlasmPackageVersion>

    <ProduceReferenceAssembly>false</ProduceReferenceAssembly>

  </PropertyGroup>

</Project>

Наконец, скопируйте созданный файл RoundTrip.il в каталог проекта. Скомпилируйте сборку с применением .NET Core CLI:

dotnet build

Результирующие файлы будут находиться, как обычно, в подкаталоге bindebugnet5.0. На этом этапе новое приложение можно запустить. Разумеется, в окне консоли отобразится обновленное сообщение. Хотя приведенный простой пример не является особенно впечатляющим, он иллюстрирует один из сценариев применения возвратного проектирования на CIL.

Директивы и атрибуты CIL

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

1 ... 345 346 347 348 349 350 351 352 353 ... 642
На этой странице вы можете бесплатно читать книгу Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю бесплатно.
Похожие на Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю книги

Оставить комментарий