10 ответов:
посмотреть Java Native Interface: Начало Работы.
2.1 обзор
[...] напишите простое приложение Java, которое вызывает функцию C для печати "Здравствуй, Мир!". Процесс состоит из следующих шагов:
создать класс (HelloWorld.java), который объявляет собственный метод. Использовать javac для компиляции исходного файла HelloWorld, в результате чего класс файл HelloWorld.класс. Компилятор javac-это поставляется с JDK или Java 2 выпуска SDK. Используйте
javah -jniдля создания файла заголовка C (HelloWorld.h), содержащий прототип функции для собственный метод реализация. Инструмент javah поставляется с JDK или Java 2 SDK выпуск. Писать на Си (HelloWorld.c) родной метод. Скомпилируйте реализацию C в собственную библиотеку, создавHello-World.dllилиlibHello-World.so. Используйте компилятор и компоновщик C доступно в среде хоста. Запустите программу HelloWorld с помощью ява интерпретатор времени выполнения. Оба файла класса (HelloWorld.class) и родная библиотека (HelloWorld.dllилиlibHelloWorld.so) загружаются во время выполнения. В оставшейся части этой главы описываются следующие шаги: деталь.2.2 объявить собственный метод
вы начинаете с написания следующей программы в программировании Java язык. Программа определяет класс с именем HelloWorld, который содержит родной метод, печать.
class HelloWorld { private native void print(); public static void main(String[] args) { new HelloWorld().print(); } static { System.loadLibrary("HelloWorld"); } }определение класса HelloWorld начинается с объявления собственного метода печати. За этим следует основной метод, который создает экземпляр класса Hello-World и вызывает собственный метод print для этого экземпляра. Последняя часть определения класса является статической инициализатор, который загружает собственную библиотеку, содержащую реализация собственного метода печати.
есть два различия между объявлением собственного метода как печать и объявление регулярных методов в Ява алгоритмический язык. Собственное объявление метода должно содержать родной модификатор. Модификатор native указывает, что этот метод реализовано на другом языке. Также объявление метода завершается точкой с запятой, символом оператора terminator, потому что в классе нет реализации для собственных методов себя. Мы реализуем метод печати в отдельном C-файле.
прежде чем можно будет вызвать собственный метод print, библиотека инструменты печати должны быть загружены. В этом случае, мы загружаем родной библиотека в статическом инициализаторе
HelloWorldкласса. ява виртуальная машина автоматически запускает статический инициализатор раньше вызов любых методов вHelloWorldкласс, таким образом гарантируя что собственная библиотека загружается перед вызовом метода Print native.мы определяем основной метод, чтобы иметь возможность запускать
HelloWorldкласса.Hello-World.mainвызывает собственный метод print в том же образом, как это вызовет обычный метод.
System.loadLibraryпринимает имя библиотеки, находит собственную библиотеку, которую соответствует этому имени, и загружает собственную библиотеку в приложение. Мы обсудим точный процесс загрузки позже в книга. Сейчас просто помните, что для того, чтобыSystem.loadLibrary("HelloWorld")чтобы добиться успеха, нам нужно создать родная библиотека называетсяHelloWorld.dllна Win32, илиlibHelloWorld.soon Солярис.2.3 скомпилировать класс HelloWorld
после того, как вы определили класс HelloWorld, сохранить исходный код в файл с именем HelloWorld.Ява. Затем скомпилируйте исходный файл с помощью компилятор javac, который поставляется с выпуском JDK или Java 2 SDK:
javac HelloWorld.javaэта команда создаст
HelloWorld.classфайл в текущем каталоге.2.4 создайте собственный файл заголовка метода
Далее мы будем использовать
javahинструмент для создания файла заголовка в стиле JNI это полезно при реализации собственного метода в C. Вы можете запуститьjavahнаHello-Worldкласса следующим образом:javah -jni HelloWorldимя файла заголовка - это имя класса с помощью"
.h" прилагается к концу. Команда, показанная выше создает файл с именемHelloWorld.h. Мы не будем перечислять созданный заголовочный файл в полном объеме здесь. Самая важная часть заголовочный файл с прототипом функции дляJava_HelloWorld_print, которым является ли функция C, которая реализует Адский мир.метод печати:JNIEXPORT void JNICALL Java_HelloWorld_print (JNIEnv *, jobject);игнорировать
JNIEXPORTиJNICALLмакросы на данный момент. Возможно, вы заметили что реализация c собственного метода принимает два аргумента даже если соответствующее объявление собственного метода принимает никакой аргумент. Первый аргумент для каждого собственного метода реализация - этоJNIEnvуказатель на интерфейс. Второй аргумент ссылка наHelloWorldобъект (вроде "this" указатель в С.)++ Мы обсудим, как использоватьJNIEnvинтерфейс указатель и тоjobjectаргументы позже в этой книге, но это просто пример игнорирует оба аргумента.2.5 написать реализацию собственного метода
файл заголовка в стиле JNI, созданный
javahпомогает вам написать C или Реализации C++ для собственного метода. Функция, которую вы пишете необходимо следовать параметру-prototype, указанному в созданном заголовочном файле. Вы можно реализоватьHello-World.printметод в файле CHelloWorld.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; }реализация этого собственного метода проста. Он использует функцию printf для отображения строки " Hello World!- а потом возвращается. Как упоминалось ранее, оба аргумента,
JNIEnvуказатель и ссылка на объект, игнорируются.программа C включает в себя три файла заголовка:
jni.h-- этот файл заголовка предоставляет информацию, необходимую для собственного кода вызов функции JNI. При написании собственных методов, вы всегда должны включите этот файл в исходные файлы C или C++.stdio.h-- код фрагмент выше, также включает в себяstdio.hпотому что он используетprintfфункция.HelloWorld.h-- файл заголовка, который вы создали с помощьюjavah. Он включает в себя прототип C / C++ дляJava_HelloWorld_printфункция. 2.6 скомпилируйте исходный код C и создайте собственную библиотекупомните, что когда вы создали
HelloWorldкласса вHelloWorld.javafile, вы включили строку кода, которая загрузила собственный библиотека в программе:System.loadLibrary("HelloWorld");теперь, когда все необходимые код C написано, вам нужно скомпилировать
Hello-World.cи построить этот родной библиотека.различные операционные системы поддерживают различные способы построения родной библиотеки. В Solaris следующая команда создает общую библиотеку называется libHello-World.so:
cc -G -I/java/include -I/java/include/solaris HelloWorld.c -o libHelloWorld.soпараметр-G указывает компилятору C чтобы создать общую библиотеку вместо обычного Solaris исполняемый файл. Из-за ограничения ширины страницы в этой книге, мы разбить командную строку на две строки. Вам нужно ввести команду в одной строке или поместите команду в файл сценария. На
Win32, следующая команда создает динамическую библиотеку (DLL)HelloWorld.dllиспользование компилятора Microsoft Visual C++:cl -Ic:\java\include -Ic:\java\include\win32 -MD -LD HelloWorld.c -FeHelloWorld.dllThe
-MDозначает, чтоHelloWorld.dllсвязан сWin32многопоточная библиотека Си. Элемент-LDпараметр указывает компилятору C генерировать DLL вместо A обычный исполняемый файл Win32. Конечно, на Солярис и Win32 вас нужно поставить в include пути, которые отражают настройку по своему усмотрению машина.2.7 запустите программу
на данный момент у вас есть два компонента, готовых для запуска программы. Файл класса (
HelloWorld.class) вызывает собственный метод, и родная библиотека (Hello-World.dll) реализует собственный метод.потому что
HelloWorldкласс содержит свой собственный основной метод, вы можете запустить программа на Solaris или Win32 выглядит следующим образом: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файл находится в текущем каталог, вы можете оформить следующие две команды в стандарте shell (sh) или KornShell (ksh) для настройкиLD_LIBRARY_PATHпеременная окружения правильно:LD_LIBRARY_PATH=. export LD_LIBRARY_PATHэквивалентная команда в оболочка C (csh или tcsh) выглядит следующим образом:
setenv LD_LIBRARY_PATH .если вы работаете на Windows 95 или Машина Windows NT, убедитесь, что
HelloWorld.dllв текущем каталог или в каталог, указанный в переменной окружения PATH переменная.в Java 2 SDK 1.2 релиз, вы также можете указать родную библиотеку путь в командной строке java как системное свойство выглядит следующим образом:
java -Djava.library.path=. HelloWorld"
-D" параметр командной строки задает системное свойство платформы Java. Установкаjava.library.pathсобственность на "." указывает виртуальной машине Java на поиск собственные библиотеки в текущем каталоге.
проще говоря, просто убедитесь, что вы загружаете соответствующую библиотеку, содержащую определение функции, загружаете библиотеку, которая следует спецификации JNI и обертывает целевую функцию из первой библиотеки, выставляет собственные методы из вашего класса Java, и вам должно быть хорошо идти.
Я бы рекомендовал против raw JNI, так как он содержит много шаблонного кода, и вы в конечном итоге проклянете себя, если начнете обертывать большой библиотеки C. Все это означает почувствовать себя свободно баловаться в JNI при запуске, но использовать что-то вроде JNA когда дело доходит до реальной работы.
опции включают в себя:
Java Native Interface
смотрите:https://en.wikipedia.org/wiki/Java_Native_Interfaceцитата:
JNI позволяет программистам писать собственные методы для обработки ситуаций, когда приложение не может быть написано полностью на языке программирования Java, например, когда стандартная библиотека классов Java не поддерживает специфические для платформы функции или программы библиотека
Java Native Access
см.:https://en.wikipedia.org/wiki/Java_Native_Access
цитата:
Java Native Access-это библиотека, разработанная сообществом, которая обеспечивает легкий доступ программ Java к собственным общим библиотекам без использования собственного интерфейса Java.
JNR-FFI
посмотреть: https://github.com/jnr/jnr-ffi
цитата:
jnr-ffi - это библиотека java для загрузки собственных библиотек без написания кода JNI вручную или с помощью таких инструментов, как SWIG.
в категории "экзотика" см. NestedVM, который компилирует C в Mips и запускает Mips Виртуальной машины внутри виртуальной машины.
Проверка JNAerator. https://code.google.com/p/jnaerator/
вы должны предоставить исходный код и определения препроцессора и т. д.
Если вы используете Windows и MinGW gcc, вам может понадобиться дополнительный флаг, если вы получаете неудовлетворенный Linkerror для конкретного метода в lib:
gcc -D_JNI_IMPLEMENTATION_ -Wl,--kill-at -I"%JAVA_HOME%"\include -I"%JAVA_HOME%"\include\win32 BestCode.c -shared -o BestCode.dll
для создания 64-разрядной совместимой dll удалите параметр "- MD " из инструкции ниже
"сл -СК:\Ява\включать -СК:\Ява\включить\Win32 с -МД-ЛД типа HelloWorld.c-FeHelloWorld.DLL-файл"
У меня есть решение этой проблемы. Вам нужно убедиться, что вы компилируете код с помощью 64-разрядного компилятора c++ для вызова функции java, работающей на 64-разрядной JRE. Вместе с этим нам нужно сохранить путь к созданному dll-файлу в "Path" в разделе "переменная окружения".
сначала убедитесь, чтобы загрузить свою родную библиотеку или .dll-файл в пути к классу, установив путь в свойстве
java.library.pathзатем использовать
System.loadLibrary()Do not use .dll extension at the end.
Comments