Jump to content

Собственный интерфейс Java

(Перенаправлено с JNI )

В разработке программного обеспечения Java Native Interface ( JNI ) представляет собой интерфейса внешних функций программирования среду , которая позволяет коду Java , работающему на виртуальной машине Java (JVM), вызывать и вызываться [ 1 ] собственные приложения (программы, специфичные для аппаратной платформы и платформы операционной системы ) и библиотеки, написанные на других языках, таких как C , C++ и ассемблер .

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

Платформа JNI позволяет собственному методу использовать объекты Java так же, как эти объекты использует код Java. Собственный метод может создавать объекты Java, а затем проверять и использовать эти объекты для выполнения своих задач. Собственный метод также может проверять и использовать объекты, созданные кодом приложения Java.

Только приложения и подписанные апплеты могут вызывать JNI.

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

Собственный код может не только взаимодействовать с Java, но и опираться на Java. Canvas, что возможно с помощью собственного интерфейса Java AWT . Процесс практически тот же, с небольшими изменениями. Собственный интерфейс Java AWT доступен только начиная с J2SE 1.3.

JNI также обеспечивает прямой доступ к ассемблерному коду , даже не проходя через C. мост [ 2 ] Доступ к Java-приложениям из сборки возможен таким же образом. [ 3 ]

В среде JNI собственные функции реализуются в отдельных файлах .c или .cpp. (C++ предоставляет немного более простой интерфейс с JNI.) Когда JVM вызывает функцию, она передает JNIEnv указатель, а jobject указатель и любые аргументы Java, объявленные методом Java. Например, следующее преобразует строку Java в собственную строку:

extern "C"
JNIEXPORT void JNICALL Java_ClassName_MethodName
  (JNIEnv *env, jobject obj, jstring javaString)
{
    const char *nativeString = env->GetStringUTFChars(javaString, 0);

    //Do something with the nativeString

    env->ReleaseStringUTFChars(javaString, nativeString);
}

The env Указатель — это структура, содержащая интерфейс для JVM. Он включает в себя все функции, необходимые для взаимодействия с JVM и работы с объектами Java. Примерами функций JNI являются преобразование собственных массивов в/из массивов Java, преобразование собственных строк в/из строк Java, создание экземпляров объектов, выдача исключений и т. д. По сути, все, что может сделать код Java, можно сделать с помощью JNIEnv, хотя и с гораздо меньшей легкостью.

Аргумент obj является ссылкой на объект Java, внутри которого объявлен этот собственный метод.

Собственные типы данных могут быть сопоставлены с типами данных Java или из них. Для составных типов, таких как объекты, массивы и строки, собственный код должен явно преобразовывать данные, вызывая методы в JNIEnv.

Указатель среды JNI ( JNIEnv* ) передается в качестве аргумента для каждой встроенной функции, сопоставленной с методом Java, что позволяет взаимодействовать со средой JNI внутри собственного метода. Этот указатель интерфейса JNI можно сохранить, но он остается действительным только в текущем потоке. Другие потоки должны сначала вызвать AttachCurrentThread(), чтобы подключиться к виртуальной машине и получить указатель интерфейса JNI. После подключения собственный поток работает как обычный поток Java, выполняющийся в собственном методе. Собственный поток остается подключенным к виртуальной машине до тех пор, пока она не вызовет DetachCurrentThread() для отсоединения. [ 4 ]

Платформа JNI не обеспечивает никакой автоматической сборки мусора для ресурсов памяти, отличных от JVM, выделяемых кодом, выполняющимся на собственной стороне. Следовательно, собственный код (например, язык ассемблера) берет на себя ответственность за явное освобождение любых таких ресурсов памяти, которые приобретает собственный код.

На платформах Linux и Solaris, если собственный код регистрируется как обработчик сигналов, он может перехватывать сигналы, предназначенные для JVM. Цепочку ответственности можно использовать, чтобы обеспечить лучшее взаимодействие машинного кода с JVM. На платформах Windows структурированная обработка исключений (SEH) может использоваться для упаковки собственного кода в блоки try/catch SEH, чтобы перехватывать программные прерывания, генерируемые машиной (CPU/FPU) (например, нарушения доступа к нулевому указателю и операции деления на ноль). ), и обрабатывать эти ситуации до того, как прерывание будет передано обратно в JVM (т. е. на сторону Java-кода), что, по всей вероятности, приведет к необработанному исключению. [ оригинальное исследование? ]

Кодировка, используемая для функций NewStringUTF, GetStringUTFLength, GetStringUTFChars, ReleaseStringUTFChars и GetStringUTFRegion, — «модифицированная UTF-8». [ 5 ] что не является действительным UTF-8 для всех входов, но на самом деле это другая кодировка. Нулевой символ (U+0000) и кодовые точки, не относящиеся к базовой многоязычной плоскости (больше или равные U+10000, т. е. представленные как суррогатные пары в UTF-16), в модифицированном UTF-8 кодируются по-разному. Многие программы на самом деле используют эти функции неправильно и обрабатывают строки UTF-8, возвращаемые или передаваемые в функции, как стандартные строки UTF-8, а не модифицированные строки UTF-8. Программы должны использовать функции NewString, GetStringLength, GetStringChars, ReleaseStringChars, GetStringRegion, GetStringCritical и ReleaseStringCritical, которые используют кодировку UTF-16LE в архитектурах с прямым порядком байтов и UTF-16BE в архитектурах с прямым порядком байтов, а затем использовать кодировку от UTF-16 до UTF- 8 процедур преобразования. [ оригинальное исследование? ]

Типы сопоставлений

[ редактировать ]

В следующей таблице показано сопоставление типов между Java (JNI) и машинным кодом.

Тип С Тип языка Java Описание Введите подпись
беззнаковый символ
uint8_t
jboolean беззнаковые 8 бит С
подписанный символ
int8_t
jbyte подписанные 8 бит Б
беззнаковый короткий
uint16_t
Джчар беззнаковые 16 бит С
короткий
int16_t
jshort подписанные 16 бит С
интервал
int32_t
шутка подписанные 32 бита я
долго долго
int64_t
Джлонг подписанные 64 бита Дж
плавать jfloat 32 бита Ф
двойной jdouble 64 бита Д
пустота V

Кроме того, подпись "L fully-qualified-class ;" будет означать класс, однозначно определенный этим именем; например, подпись "Ljava/lang/String;" относится к классу java.lang.String. Кроме того, префикс [ в подпись составляет массив этого типа; например, [I означает тип массива int. Наконец, void подпись использует V код.

Эти типы взаимозаменяемы. Можно использовать jint где вы обычно используете intи наоборот, без необходимости приведения типов . Однако сопоставление строк и массивов Java с собственными строками и массивами отличается. Если jstring используется там, где char * будет, код может привести к сбою JVM. [ оригинальное исследование? ]

Производительность

[ редактировать ]

JNI несет значительные накладные расходы и потерю производительности при определенных обстоятельствах: [ 6 ]

  • Вызовы функций методов JNI являются дорогостоящими, особенно при многократном вызове метода.
  • Собственные методы не встроены в JVM, и метод не может быть скомпилирован JIT , поскольку метод уже скомпилирован.
  • Массив Java можно скопировать для доступа в собственном коде, а затем скопировать обратно. Стоимость может быть линейной в зависимости от размера массива.
  • Если методу передается объект или ему необходимо выполнить обратный вызов, то собственный метод, скорее всего, будет выполнять собственные вызовы JVM. Доступ к полям, методам и типам Java из нативного кода требует чего-то похожего на отражение . Сигнатуры указываются в строках и запрашиваются у JVM. Это медленно и подвержено ошибкам.
  • Строки Java являются объектами, имеют длину и закодированы. Для доступа к строке или ее создания может потребоваться копирование O(n).

Альтернативы

[ редактировать ]

Собственная реализация виртуальной машины Java от Microsoft ( Visual J++ ) имела аналогичный механизм для вызова собственного кода Java, называемый Raw Native Interface ( RNI ). Кроме того, у него был простой способ вызова существующего собственного кода, который сам не знал о Java, такого как (но не ограничиваясь) Windows API, называемый J/Direct . Однако после судебного разбирательства между Sun и Microsoft по поводу этой реализации Visual J++ больше не поддерживается.

RNI был менее неуклюжим в использовании, чем JNI, поскольку не требовалось никакого учета указателя среды Java. Вместо этого ко всем объектам Java можно было получить прямой доступ. Чтобы облегчить это, использовался инструмент, который генерировал файлы заголовков из классов Java. Точно так же J/Direct было проще использовать, чем использовать необходимую промежуточную собственную библиотеку и JNI.

Java Native Access (JNA) — это разработанная сообществом библиотека, которая предоставляет Java-программистам легкий доступ к собственным общим библиотекам без использования JNI. Однако для этого требуется перераспределение зависимой библиотеки jar. Компромисс заключается в том, что JNI сложнее кодировать, а JNA медленнее. [ 7 ] JNI встроен в ядро ​​Java.

См. также

[ редактировать ]
  1. ^ «Обзор собственного интерфейса Java» . Руководство и спецификация для программиста собственного интерфейса Java . Проверено 27 декабря 2018 г.
  2. ^ «Вызов программ на языке ассемблера из Java» . Java.net. 19 октября 2006 г. Архивировано из оригинала 30 марта 2008 г. Проверено 6 октября 2007 г.
  3. ^ «Запуск приложений Java из программ на языке ассемблера» . Java.net. 19 октября 2006 г. Архивировано из оригинала 11 октября 2007 г. Проверено 4 октября 2007 г.
  4. ^ API вызова. Сан Микросистемс. https://docs.oracle.com/en/java/javase/11/docs/specs/jni/invocase.html
  5. ^ «Типы JNI и структуры данных» .
  6. ^ «java — Что делает вызовы JNI медленными? - Stack Overflow» .
  7. ^ Закусило, Александр. «Github также является оригинальным источником JNA. Тесты скорости тестов JNA и JNI» . Гитхаб . Гитхаб . Проверено 30 марта 2023 г.

Библиография

[ редактировать ]
[ редактировать ]
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: 9efd29eb2962a69fe1889d7a3c1fc64e__1697692680
URL1:https://arc.ask3.ru/arc/aa/9e/4e/9efd29eb2962a69fe1889d7a3c1fc64e.html
Заголовок, (Title) документа по адресу, URL1:
Java Native Interface - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)