Думай на Java

       

Доступ к JNI функциям: аргументы JNIEnv


Под функциями JNI подразумеваются функции, которые взаимодействуют с JVM из собственных методов. Как вы могли видеть в приведенном выше примере, каждый собственный метод JNI получает специальный аргумент в качестве первого параметра: это и есть JNIEnv аргумент, который является указателем на специальную структура данных типа JNIEnv_. Один из элемент структуры данных JNI является указателем на массив генерируемый JVM. Массив состоит из указателей на JNI функции. JNI функции могут быть вызваны из собственного метода путем разыменования данных указателей (это проще чем кажется). Каждая JVM обеспечивает собственной реализацией JNI функций, но их адреса всегда остаются на определенном месте.

С помощью аргументов JNIEnv программе доступно большое количество функций. Эти функции могут быть сгруппированы в следующие категории:

  • Получение информации о версии
  • Выполнение операций с классами и объектами
  • Использование глобальных и локальных ссылок на Java объекты
  • Доступ к полям ссылки и статическим полям
  • Вызов ссылочных методов и статических методов
  • Выполнение операций со строками и массивами
  • Генерация и перехват Java исключений
  • Количество JNI функций достаточно большое и не может быть описано здесь. Вместо этого покажем логическое обоснование использования этих функций. Более детальная информация находиться в документации по JNI.

    Если посмотреть на заголовочный файл jni.h можно видеть что внутри условий препроцессора #ifdef __cplusplus структура JNIEnv_ определена как класс когда компилируется С++ компилятором. Данный класс содержит несколько функций, которые позволяют вам получить доступ к JNI функциям через простой и знакомый синтаксис. В качестве иллюстрации приведем строку кода из рассмотренного примера:

    env->ReleaseStringUTFChars(jMsg, msg);

    также может быть вызвано из С следующим образом:

    (*env)->ReleaseStringUTFChars(env, jMsg, msg);

    Вы заметили, что строка на С гораздо сложнее (что естесственно) - вам необходимо двойное разыменование указателя на env. Вы также должны передать этот указатель в качестве первого параметра при вызове JNI функции. Примеры данного приложения используют С++ стиль.



    Содержание раздела