java swing html - Использовать JNI вместо JNA для вызова собственного кода?





4 Answers

Трудно ответить на такой общий вопрос. Я полагаю, что наиболее очевидным отличием является то, что с JNI преобразование типов реализовано на родной стороне Java / родной границы, а с JNA преобразование типов реализовано на Java. Если вы уже чувствуете себя вполне комфортно с программированием на C и должны сами реализовать собственный код, я бы предположил, что JNI не будет казаться слишком сложным. Если вы программист на Java и вам нужно только вызывать стороннюю библиотеку, использование JNA, вероятно, является самым простым путем, чтобы избежать, возможно, не столь очевидных проблем с JNI.

Хотя я никогда не сравнивал какие-либо различия, я бы из-за дизайна, по крайней мере, предположил, что преобразование типа с JNA в некоторых ситуациях будет хуже, чем с JNI. Например, при передаче массивов JNA будет преобразовывать их из Java в native в начале каждого вызова функции и обратно в конце вызова функции. С JNI вы можете управлять собой, когда генерируется собственное «представление» массива, потенциально только создавая представление о части массива, сохраняя представление по нескольким вызовам функций и в конце релиза представления и решая, хотите ли вы сохранить изменения (возможно, потребовать, чтобы скопировать данные назад) или отказаться от изменений (без необходимости копирования). Я знаю, что вы можете использовать собственный массив для вызовов функций с помощью JNA с использованием класса памяти, но для этого также потребуется копирование памяти, что может быть ненужным с JNI. Разница может быть неактуальной, но если ваша первоначальная цель - увеличить производительность приложения, реализовав ее части в собственном коде, использование хуже используемой мостовой технологии, по-видимому, не является самым очевидным выбором.

css text component

JNA кажется более легким в использовании для вызова собственного кода по сравнению с JNI. В каких случаях вы бы использовали JNI над JNA?




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




Если вам нужна производительность JNI, но ее сложно устранить, вы можете использовать инструменты, которые автоматически создают привязки JNI. Например, JANET (отказ от ответственности: я написал его) позволяет смешивать Java и C ++-код в одном исходном файле и, например, совершать вызовы с C ++ на Java с использованием стандартного синтаксиса Java. Например, вот как вы должны напечатать строку C для стандартного вывода Java:

native "C++" void printHello() {
    const char* helloWorld = "Hello, World!";
    `System.out.println(#$(helloWorld));`
}

Затем JANET переводит внедренную в обратную сторону Java в соответствующие вызовы JNI.




Если я что-то не хватает, не главное отличие JNA от JNI от того, что с JNA вы не можете вызывать код Java из native (C) кода?




Related