Книга: C# для профессионалов. Том II
Компиляция
Компиляция
При описании некоторых различий между JRE Java и CLR C# кратко упоминались некоторые детали того, как написанный на соответствующем языке код компилируется и выполняется. Хотя код обоих языков компилируется в некоторую промежуточную форму, байт-код версии Java никогда не компилируется повторно в собственные инструкции машины (если только не используется компилятор в собственный код). Вместо этого байт-код требует для выполнения среду времени выполнения, и в частности, виртуальную машину. Имя компилированного файла связано с именем файла, в котором находится исходный код, который в свою очередь связан с именем открытого класса в этом файле. В случае определения нескольких классов в одном файле каждое определение класса будет создавать файл класса, который соответствует имени определенного класса. Например, возьмем исходный файл Test.java
со следующим кодом:
// Test.java
class x {}
class у {}
class z {}
Компиляция этого файла будет создавать три файла классов: х.class
, у.class
, z.class
. Один (и только один для каждого исходного файла) из этих классов может быть объявлен открытым следующим образом:
// Test.java
public class x {}
class у {}
class z {}
В приведенном выше примере имя исходного файла Test.java
должно быть изменено, чтобы соответствовать имени находящегося в нем открытого класса. Test.java
поэтому станет х.java
, чтобы код компилировался.
В противоположность этому, компилированный в IL код C# выполняется VES (Virtual Execution System), которая предоставляет поддержку для IL, загружая управляемый код, и JITters (которые преобразуют управляемый код в форме промежуточного языка в собственный код машины). Имя файла Hello.cs
не связано с именем конечного исполняемого файла и может изменяться во время компиляции с помощью ключа /out
. Если имя файла вывода не определено, то exe получит имя того файла исходного кода, который содержит метод main
, a DLL получит имя первого указанного файла исходного кода. Фактически имя файла даже не связано с определениями любых классов, находящихся в файле. Класс Hello
может быть определен в файле Goodbу.cs
, который компилируется в несвязанный MisterHanky.exe
.
SDK .NET поставляется вместе с компилятором, поэтому не нужно беспокоиться о получении специальных компиляторов для этого приложения. Откройте просто командную строку, перейдите в каталог, где сохранен файл hello.cs
, и введите:
csc hello.cs
Файл будет компилирован в hello.exe
. Хотя большинство программистов Java знакомы с этой формой низкоуровневой компиляции, важно заметить, что Visual Studio.NET предоставляет аналогичную функциональность, интегрированную в IDE. Например, изменение имени исполнимого файла можно легко выполнить, добавляя свойство имени сборки страницы свойств проекта. Чтобы сделать это производим щелчок правой кнопкой мыши на имени проекта в панели Solution Explorer и выбираем Properties или указываем Project в меню, в то время, когда имя проекта выделено, и выбираем пункт меню Properties. В папке Common Properties можно выбрать страницу General Properties и изменить свойство Assembly Name. Можно будет увидеть, что свойство для чтения Output File изменяется, отражая новое имя сборки.
Типы компиляции
Все файлы Java компилируются в файл байт-кода с расширением .class
, который может выполниться виртуальной машиной. Внутри первого исходного кода необходимо предоставить соответствующую. Функциональность для создания того или иного типа приложения. Например, определенный ниже код будет создавать окно, аналогичное Form
в Windows. Второй исходный файл AddLib.java
является вспомогательным классом, используемым для выполнения сложения двух целых чисел. Можно заметить, что они включены в отдельные пакеты и JavaFrame
импортирует класс AddLib
. Пакеты и их эквивалент C# будут рассмотрены в следующем разделе:
// код для JavaFrame.java
Package com.javaapp;
import java.awt.*;
import java.io.*;
import com.javalib.AddLib;
public class JavaFrame extends java.awt.Frame {
public static void main (String[] args) {
JavaFrame jfrm = new JavaFrame();
jfrm.setSize(100, 100);
jfrm.setVisible(true);
AddLib lib = new AddLib();
jfrm setTitle("Frame Version " + lib.operationAdd(12, 23));
}
}
// код для AddLib.java
Package com.javalib;
public class AddLib {
public AddLib() {
}
public int operationAdd(int a, int b) {
return a + b;
}
}
Java предоставляет двухшаговый процесс для создания исполнимого файла или библиотечных единиц компиляции: откомпилировать файл(ы) и сделать файл доступным, предоставляя компилятору путь доступа к папке, где находятся файлы (можно написать пакетный файл, который будет делать это за один шаг). Класс можно сделать доступным с помощью ключа компилятора -classpath
для определения, где компилятор может искать разрешение символов, не определенных в исходном коде (различные компиляторы могут иметь различные имена для этого ключа). Система имеет также переменную среды окружения Classpath
. Если ключ -classpath
не определен, то компилятор будет искать переменную окружения, если ключ -classpath
определен, то он переопределяет любые записи Classpath
, которые могут существовать среди переменных окружения для этой специфической компиляции.
Классы могут также объединяться в файл JAR, который необходимо сделать доступным таким же образом, как и папку, содержащую в себе класс. Классы внутри или вне файла JAR могут быть или не быть частью нуля или большего числа пакетов. В приведенном выше примере JavaFrame
и AddLib
необходимо будет откомпилировать в файлы классов. Путь доступа к этим файлам классов можно затем добавить к переменной окружения CLASSPATH
. Когда путь доступа к классам задан, любые классы из пакета могут выполняться из любого каталога в системе, передавая полностью квалифицированное имя класса в виртуальную машину. Вызов с помощью SUN Microsystems JDK 1.3:
java javalib.JavaFrame
приводит к выполнению программы JavaFrame
и созданию Frame
с панелью заголовка, выводящей Java Frame Version 35.
Код в C# всегда после компиляции автоматически объединяется в тот или иной тип компонента. Единицы компиляции могут содержать столько файлов и определений классов, сколько потребуется. Способ использования этой функциональности снова делится между использованием командной строки и использованием IDE (в частности, Visual Studio.NET). Создание нового проекта с помощью VS.NET требует, чтобы был определен тип создаваемого проекта. Среди других имеются возможности создать консольное приложение, оконное приложение и библиотеку классов. Можно создать даже пустой проект и определить тип вывода позже. Процесс определения типа вывода проекта с помощью VS.NET описан дальше в этом разделе. В командной строке для изменения типа вывода используется ключ /target: <target-type>
, где target-type
является одной из строк:
? Ехе
? Library
? Winexe
Можно добавить любое число файлов как аргументы, разделенные пробелами:
csc /target:<target-type> <file1> <file2> ... <filen>
Добавление нескольких файлов в единицу компиляции с помощью VS.NET является вопросом добавления отдельных файлов в проект. Можно легко изменить тип выходного файла, поменяв свойство Output Type на странице General Properties (смотрите выше детали доступа к странице с общими свойствами).
- 3.8.3. Компиляция ядра
- Компиляция ядра
- 15.2. Компиляция для отладки
- Компиляция и установка ядра
- Компиляция вне дерева исходных кодов ядра
- Почему компиляция?
- Компиляция регулярных выражений
- Компиляция Си-программы на IBM PC (компиляторы Microsoft С и Lattice С)
- Условная компиляция
- Компиляция с библиотекой curses
- 1.2.1. Компиляция одного исходного файла
- 1.4.1. Компиляция с включением отладочной информации