C++ и Java: совместное использование
Страница 8. JNI функции


JNI функции

JNI определяет 210 прикладных функций. Доступ к ним из С/С++-функции можно получить через интерфейсный указатель JNIENV*, который передается каждой С/С++-функции, представлющей реализацию собственного метода. Все функции разделены на 14 групп:

  • информация о версии JNI;
  • операции с классами;
  • исключения (EXCEPTIONS);
  • обработка глобальных и локальных ссылок;
  • операции с объектами;
  • доступ к данным объекта;
  • вызов методов объекта (INSTANCE METHOD);
  • доступ к статическим данным объекта;
  • вызов методов класса (CLASS METHOD);
  • операции со строковыми объектами;
  • операции с массивами;
  • регистрация собственных методов;
  • операции с мониторами (MONITOR OPERATIONS);
  • интерфейс с JVM.

Использование JNI функций необходимо только в том случае, если С/С++-функция осуществляет какое-либо взаимодействие с JVM: вызов JAVA-методов, доступ к данным, создание JAVA-объектов и т.д.

Ниже приведен пример JAVA-программы, которая выводит на печать количество свободной памяти на диске С для платформы WIN32. Для этого используется собственный метод и соответствующая реализационная С/С++-функция, вызывающая при своей работе функцию WIN32 API.

// Файл APP.JAVA
PUBLIC CLASS APP {
PUBLIC STATIC VOID MAIN(STRING ARGS[]) {
SYSTEMSPECIFIC SS = NEW SYSTEMSPECIFIC();
TRY {
LONG BYTES = SS.GETCDRIVEFREESPACE();
IF (BYTES != -1) {
LONG KB = BYTES / 1024;
SYSTEM.OUT.PRINTLN("на диске C:\\ свободно " + KB + " KB");
}
ELSE {
SYSTEM.OUT.PRINTLN("произошла ошибка в С/С++-функции");
}
}
CATCH (UNSATISFIEDLINKERROR E) {
SYSTEM.OUT.PRINTLN("метод не найден (" + E + ")");
}
}
}
CLASS SYSTEMSPECIFIC {
STATIC {
TRY {
SYSTEM.LOADLIBRARY("SYSSPEC");
}
CATCH (UNSATISFIEDLINKERROR E) {
SYSTEM.OUT.PRINTLN("библиотека не найдена (" + E + ")");
}
}
NATIVE LONG GETCDRIVEFREESPACE();
}
// Файл SYSTEMSPECIFIC.CPP
#INCLUDE "SYSTEMSPECIFIC.H"
#INCLUDE <WINDOWS.H>
JNIEXPORT JLONG JNICALL JAVA_SYSTEMSPECIFIC_GETCDRIVEFREESPACE (JNIENV *, JOBJECT) {
DWORD SCTRPERCLSTR, BYTESPERSCTR, FREECLSTR, CLSTR;
BOOL RES = GETDISKFREESPACE("C:\\", &SCTRPERCLSTR, &BYTESPERSCTR, &FREECLSTR, &CLSTR);
RETURN RES == TRUE ? SCTRPERCLSTR * BYTESPERSCTR * FREECLSTR : -1;
}

Для успешной компиляции кода JAVA и С/С++ на платформе WIN32 необходимо правильно установить переменные окружения PATH, LIB, INCLUDE и CLASSPATH (многие из этих значений можно задать как параметры соответствующих компиляторов).

Если записать исходные тексты предыдущего примера в файлы APP.JAVA и SYSTEMSPECIFIC.CPP соответственно, то для их компиляции необходимо выполнить следующие команды (предполагается, что исходные файлы находятся в каталоге C:\TEST\NATIVE):

C:\TEST\NATIVE> JAVAC APP.JAVA
C:\TEST\NATIVE> JAVAH -JNI SYSTEMSPECIFIC
C:\TEST\NATIVE> CL -W3 SYSTEMSPECIFIC.CPP -FESYSSPEC.DLL -TP -LD -MD -LINK JAVAI.LIB

Для запуска программы необходимо выполнить: C:\TEST\NATIVE> JAVA APP
на диске С:\ свободно 324567 KB
C:\TEST\NATIVE>

Для трансляции С/С++-файлов можно использовать любой компилятор, допускающий создание 32-битных DLL.

 
« Предыдущая статья   Следующая статья »