C++ и Java: совместное использование - Создание собственного JAVA-метода

ОГЛАВЛЕНИЕ

 

Создание собственного JAVA-метода

Собственный метод создается путем добавления к его описанию спецификатора NATIVE, при этом он не должен иметь реализации (так же как и методы в описании интерфейса). Спецификатор NATIVE сообщает компилятору, что реализация данного метода будет представлена в виде откомпилированного С/С++-кода, помещенного в библиотечный файл. Когда JVM встречает обращение к собственному методу, происходит вызов соответствующей С/С++-функции. Помимо описания собственнного метода, JAVA-код должен динамически загрузить библиотеку, содержащую С/С++-функцию с реализацией данного метода. Для этого в классе JAVA.LANG.SYSTEM существует метод PUBLIC STATIC VOID LOADLIBRARY (STRING LIBNAME), загружающий указанную библиотеку. Следующий пример демонстрирует описание собственного метода.

CLASS SYSTEMSPECIFIC {
STATIC {
SYSTEM.LOADLIBRARY("SYSSPEC");
}
NATIVE VOID DOSPECIFIC();
}

В приведенном примере метод DOSPECIFIC() является собственным, и его С/С++-реализация находится в библиотеке SYSSPEC. Метод LOADLIBRARY() вызывается в статическом инициализаторе, что обеспечивает единственный вызов этого метода после загрузки класса SYSTEMSPECIFIC загрузчиком классов (CLASS LOADER). В принципе, LOADLIBRARY() можно вызывать более одного раза (например, в конструкторе), однако загрузка библиотеки будет происходить только при первом обращении к LOADLIBRARY(), поскольку при последующих вызовах этого метода определяется, что библиотека уже загружена и будет просто возвращаться управление.

Метод LOADLIBRARY() преобразует свой параметр в соответствии с тем, как именуются библиотечные файлы на конкретной платформе. В данном примере SYSSPEC преобразуется в SYSSPEC.DLL и LIBSYSSPEC.SO для WIN32 и UNIX соответственно. Метод LOADLIBRARY() использует стандартный алгоритм поиска библиотеки для данной платформы. Для WIN32 DLL должна находиться либо в текущем каталоге процесса, либо в каталоге, содержащем EXE-файл, то есть исполняемый модуль JVM, находящийся в подкаталоге BIN основного каталога JAVA, либо в системном каталоге WIN32, либо каталоге WINDOWS или в каталогах, указанных в переменной окружения PATH. Для UNIX библиотечный файл должен находиться либо в текущем каталоге процесса, либо в подкаталоге LIB основного каталога JAVA, либо в каталогах, перечисленных в переменной окружения LD_LIBRARY_PATH. Если указанную библиотеку найти не удается, метод LOADLIBRARY() генерирует исключительную ситуацию JAVA.LANG.UNSATISFIEDLINKERROR. Однако данная ситуация возникает не только в этом случае. Когда интерпретатор встречает вызов собственного метода, он ищет его (точнее его полную сигнатуру) в списке методов загруженных библиотек. Если метод не найден, то генерируется указанная исключительная ситуация.

Для более надежной работы с собственными методами можно использовать, к примеру, следующий код:

PUBLIC CLASS APP  {
PUBLIC STATIC VOID MAIN(STRING ARGS) {
SYSTEMSPECIFIC SS = NEW SYSTEMSPECIFIC();
TRY {
SS.DOSPECIFIC();
}
CATCH (UNSATISFIEDLINKERROR E) {
SYSTEM.OUT.PRINTLN("метод не найден (" + E + ")");
}
}
}
CLASS SYSTEMSPECIFIC {
STATIC {
TRY {
SYSTEM.LOADLIBRARY("SYSSPEC");
}
CATCH (UNSATISFIEDLINKERROR E) {
SYSTEM.OUT.PRINTLN("библиотека не найдена (" + E + ")");
}
}
NATIVE VOID DOSPECIFIC();
}

Компиляция программ, содержащих собственные методы, ничем не отличается от компиляции обычных программ. Например, если записать предыдущий пример в файл с именем APP.JAVA, то для его компиляции необходимо выполнить следующую команду:

C:\ JAVAC  APP.JAVA