Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
GoslingJava2.doc
Скачиваний:
139
Добавлен:
23.02.2016
Размер:
2.39 Mб
Скачать

А.2.1 Имена

Для перевода имен методов и полей на язык C используются полные имена, включающие названия пакетов, в которых все точки (.) заменяются подчеркиваниями (_). В тех языках, где не поддерживается возможность перегрузки методов (к ним относится C) вы не сможете реализовать в классе несколько методов с одинаковыми именами, поскольку им будет соответствовать одно и то же имя функции.

Аналогично переводятся и имена типов— за тем исключением, что перед именем типа ставится префикс Class. В программе на C тип для LockableFile будет называться Classlocal_LockableFile. Для каждого класса также необходим дескриптор (handle), поскольку он используется для внутреннего представления ссылок. Имя дескриптора совпадает с именем класса, но вместо префикса Class используется префикс H. Таким образом, тип дескриптора для LockableFile будет называться Hlocal_LockableFile.

Символы имен, относящиеся к набору ASCII (символы, меньшие или равные \u007f) переходят в C и в имена пакетов без изменений. Все остальные символы переводятся в вид _0dddd, где d— цифры, используемые в символьном представлении Java. Например, символ г (код \u00e3) будет представлен идентификатором _000e3. Косая черта (/) в имени пакета переходит в символ подчеркивания (_).

А.2.2 Методы

Каждый родной метод представляется в виде функции. Например, метод lock будет называться local_LockableFile_lock и иметь соответствующие параметры. Первый параметр функции— это дескриптор объекта, для которого вызывается метод (ссылка this). Для статических методов такой дескриптор всегда равен null. Ниже дескрипторы рассматриваются более подробно.

Для вызова методов нужен дополнительный слой в виде файлов-заглушек (stub files). Последние также генерируются утилитой javah, но с параметром -stubs:

javah -stubs local.LockableFile

Такая команда генерирует исходный файл на языке C, который должен быть скомпилирован и загружен в динамическую библиотеку вместе в реализациями родных методов. Имя этого файла совпадает с именем заголовочного файла, однако расширение h изменяется на c— в нашем случае это будет файл local_LockableFile.c.

А.2.3 Типы

В приведенной ниже таблице показано соответствие между примитивными типами Java и типами языка C, когда они используются в качестве параметров методов или полей (согласование типов для массивов рассматривается ниже).

Тип Java

Тип C

boolean

long

byte

long

short

long

int

long

long

int64_t

float

float

double

double

char

long

Классы Java представляются в языке C структурами (struct). Все нестатические поля класса являются членами структуры, а их имена совпадают с именами в Java (за исключением символов Unicode, отображаемых в эквиваленты _0dddd). Это означает, что класс, содержащий родные методы, не может иметь два нестатических поля с одинаковыми именами; в противном случае структура на языке C содержала бы члены с одинаковыми именами, что запрещено.

Проблема возникает с теми классами, которые скрывают поля суперклассов— кстати, еще одна причина, по которой не следует скрывать имена полей. Тем не менее, проблема относится даже к тем классам, которые содержат закрытые поля с тем же именем, поскольку такие поля присутствуют в структуре наравне со всеми остальными. Вы не сможете выяснить, актуальна эта проблема или нет, пока она не возникнет при написании родного метода. Дело обстоит еще хуже, если скрываемые поля находятся в суперклассе, который невозможно изменить. В таких случаях дело заходит в тупик— вы не сможете написать родной метод без модификации имен полей класса.

Каждая статическая константа с атрибутом final представлена константой #define с префиксами(именем пакета и класса). Статические поля, не являющиеся final, не переводятся ни во что. Например, тип и константы для класса LockableFile определяются в заголовочном файле следующим образом:

typedef struct Classlocal_LockableFile {

struct Hjava_lang_String *path;

/* недоступное статическое поле: separator */

/* недоступное статическое поле: separatorChar */

/* недоступное статическое поле: pathSeparator */

/* недоступное статическое поле: pathSeparatorChar */

#define local_LockableFile_READ 0L

#define local_LockableFile_WRITE 1L

long fd;

} Classlocal_LockableFile;

Ссылки на объекты представляются типом “дескриптор”, в составном имени которого Class заменяется на H. Ссылка на класс LockableFile будет называться Hlocal_LockableFile. Макрос unhand получает дескриптор и возвращает указатель на структуру, которая представляется этим дескриптором.

Ниже приведены сигнатуры функций языка C, в которых ниже мы определим родные методы класса LockableFile:

extern void local_Lockable_File_lock(

struct Hlocal_LockableFile *, long);

extern void local_Lockable_File_unlock(

struct Hlocal_LockableFile *);

В Java об ошибках сигнализируют исключения. В языке C исключений нет. Чтобы возбудить исключение из C, следует вызвать функцию SignalError и затем выйти. Runtime-система Java обнаруживает и возбуждает исключение, о котором сигнализировала функция SignalError. Ниже вы увидите несколько примеров того, как это делается.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]