понедельник, 10 октября 2016 г.

Пример использования Java Native Interface

В этом посте показан, пример использования Native Interface Java (JNI). Мы напишем приложение Java, которое вызывает функцию C, которая печатает «Hello World!».
Через что нам придется пройти?
  • Создание класса (HelloWorld.java), в котором объявлен нативный метод.
  • Использование команды javac, чтобы скомпилировать файл HelloWorld
  • Использование команды javah -jni, чтобы создать заголовочный файл HelloWorld.h, в котором будут содержаться прототипы функций для реализации нативных методов.
  • На языке С  написать методы (HelloWorld.c)
  • Создать, путем компилирования, библиотеки HelloWorld.dll или libHelloWorld.so
  • Запустить программу HelloWorld



Начнем по порядку. На java напишем класс HelloWorld, содержащий нативный метод.
class HelloWorld {
 
     static {
         System.loadLibrary("HelloWorld");
     }
 
     private native void print();
 
     public static void main(String[] args) {
         new HelloWorld().print();
     }
 }
В первой части класса используется статическая инициализация, которая загружает библиотеку, содержащую реализацию нативного метода. Затем объявлен нативный метод печати и основной метод main, который и вызывает печать через нативный метод.
Сохраним исходный код класса HelloWorld, в файле под названием HelloWorld.java. Скомпилируем файл с помощью компилятора javac следующим образом:

javac HelloWorld.java

Эта команда создаст файл HelloWorld.class в текущем каталоге.
Далее используем инструмент javah для генерирования заголовочного файла HelloWorld.h. Запустите javah следующим образом:

javah -jni HelloWorld

В текущем каталоге будет создан файл с именем HelloWorld.h. Именно этот файл и определяет JNI стиль.
Функция, которую мы пишем, в созданном файле определяет всего лишь прототип. А сам метод print реализуем в файле HelloWorld.c следующим образом:

#include <jni.h>
#include <stdio.h>
#include "HelloWorld.h"
  
JNIEXPORT void JNICALL 
Java_HelloWorld_print(JNIEnv *env, jobject obj)
{
    printf("Hello World!\n");
    return;
}

Теперь, когда на языке C, написан необходимый код, нужно скомпилировать HelloWorld.c и построить библиотеку.
Различные операционные системы поддерживают различные способы создания собственных библиотек. На Solaris создать  библиотеку с именем libHelloWorld.so можно следующей командой:

cc -G -I/java/include -I/java/include/solaris HelloWorld.c -o libHelloWorld.so

Опция -g указывает компилятору C cгенерировать библиотеку, а не обычной Solaris исполняемый файл.
На Linux команда выглядит практически идентично:

gcc -I/java/include -I/java/include/linux -o libHelloWorld.so -shared HelloWorld.c

На Win32, с помощью компилятора Microsoft Visual C ++ , посредством следующей команды создаем динамическую библиотеку HelloWorld.dll:

cl -Ic:\java\include -Ic:\java\include\win32 -MD -LD HelloWorld.c -FeHelloWorld.dll

Параметр -MD гарантирует, что HelloWorld.dll будет поддерживать многопоточность. А параметр -ld указывает компилятору C генерировать DLL вместо обычного Win32 исполняемого файла.
Во всех трех случая путь в параметре -I/java подразумевает каталог с установленной jdk.
У нас уже есть написанный класс HelloWorld, его то и можно попробовать запустить:

java HelloWorld

Вы должны увидеть следующий текст:

Hello World!

Важно, чтобы библиотека была расположена по верному пути. Java машина выполняет поиск подобных библиотек в соответствующем списке каталогов. Если библиотека не будет расположена в одном из этих каталогов, то получим сообщение об ошибке, похожее на следующее:

java.lang.UnsatisfiedLinkError: no HelloWorld in library path
        at java.lang.Runtime.loadLibrary(Runtime.java)
        at java.lang.System.loadLibrary(System.java)
        at HelloWorld.main(HelloWorld.java)

В системе Solaris, чтобы определить путь к библиотекам, используется переменная среды LD_LIBRARY_PATH. Убедитесь, что она включает в себя имя каталога, содержащего файл libHelloWorld.so. Чтобы включить текущий каталог (с файлом libHelloWorld.so), нужно выполнить следующие две команды вshell (sh) или KornShell (ksh), чтобы настроить переменную окружения LD_LIBRARY_PATH правильно:

LD_LIBRARY_PATH=.
export LD_LIBRARY_PATH

Если вы работаете под Windows, убедитесь, что HelloWorld.dll в текущем каталоге, или в каталоге, который перечислен в переменной окружения PATH.
В версии Java 2 SDK 1.2, вы можете указать путь в командной строке Java следующим образом:

java -Djava.library.path=. HelloWorld

Параметр командной строки -D задает свойство системы платформы Java. Установка свойства java.library.path в «.» обязывает виртуальную машину Java искать библиотеки в текущем каталоге.

Источник

Комментариев нет:

Отправить комментарий