3f-lab: Маленький практикум по JNI

Как и обещал, публикую рецепт на случай, если кому-то из начинающих Java-разработчиков захочется задействовать часть кода, написанного на других языках (например, C). Эта технология называется JNI (Java Native Interface) и работает по следующему алгоритму.



1) В коде, который предполагается связывать с C-библиотеками, предусматривает т.н. native методы. У них нет тела (кода, заключенного в фигурные скобки). Все алгоритмы выполняются «в dll-ках», а методы просто декларируются

package com.michaelbelyakov1967.util;

public class Win32{

 public static native String getHostName();

 static{loadLibrary("3f-win");}
}


Обратите внимание на статический блок loadLibrary(«3f-win»). Он отвечает за загрузку библиотеки и без него работать ничего не будет. В каталоге, из которого запускается программа, должна лежать скомпилированная библиотека (например, 3f-win.dll), которую как раз и предстоит создать.

2) Компилируем Java-класс (привожу соответствующий фрагмент файла build.xml):

<javac srcdir="." destdir="${classdir}">	 
   <classpath>		 
    <pathelement path="${classdir}"/>
   </classpath>		 
  </javac>


Как говорит в таких случаях Римский Папа — nihil novi.

3) Создаем т.н. заголовочный файл для программы на языке C:

<javah destdir="include">
   <class name="com.michaelbelyakov1967.util.Win32"/>	  
   <classpath>		 
    <pathelement path="${classdir}"/>
   </classpath>		 
  </javah>


После выполнения этого задания в каталоге include появится файл с длинным названием и расширением ".h". Из него и будем черпать названия методов и передаваемые аргументы для C-программы.

4) Пишем код на C в файле 3f-win.c:

#include <windows.h>
#include "com_michaelbelyakov1967_util_Win32.h"

JNIEXPORT jstring JNICALL Java_com_michaelbelyakov1967_util_Win32_getHostName (JNIEnv *env, jclass cls) {
 char *szHostName[255];
 int n = 255;
 gethostname(szHostName, n); 
 return (*env)->NewStringUTF(env, szHostName); 
}


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

5) Компилируем C-программу. Вообще говоря, сделать это можно какой-нибудь простой командой типа

gcc -o 3f-win.dll 3f-win.c


Но мы же истинные гики и программы для Windows пишем не выходя из Linux (посредством MinGW), так что вот:

<target name="cc">
  <exec executable="${mingw}">
   <arg value="-D_JNI_IMPLEMENTATION_"/>
   <arg value="-Wl,--kill-at"/>
   <arg value="-I/_bin/mingw/include/java"/>
   <arg value="-I/_bin/mingw/include/java/win32"/>
   <arg value="-Iinclude"/>
   <arg value="-shared"/>
   <arg value="-o"/>
   <arg value="${classdir}/com/michaelbelyakov1967/resources/util/3f-win.dll"/>
   <arg value="win32.c"/>
   <arg value="-lnetapi32"/>
   <arg value="-lpsapi"/>
   <arg value="-lwsock32"/>
   <arg value="-luser32"/>
  </exec>	  
 </target>


Привожу этот фрагмент как есть, т.к. у меня класс для работы с WinAPI выполняет множество полезных функций: выводит список процессов, убивает некоторые из них, перезагружает компьютер и т.д.

В результате в чистом остатке имеем файл 3f-win.dll. Если дооснастить наш класс статическим методом

public static void main(String[] args){
  System.out.println(getHostName());	
 }


и запустить его в среде Windows (не забыв положить в текущий каталог полученную dll-ку)

java -cp /_classes com.michaelbelyakov1967.util.Win32


на экране в консоли должно появиться имя хоста. Под Linux всё так же, только компилировать C-код проще.
  • +4
  • 15 марта 2010, 22:05
  • yababay

Комментарии (5)

RSS свернуть / развернуть
+
0
Пора мне приковаться к столу и уже начать программить еклмн
столько времени уходит на беготню аж ппц
avatar

Sergei_T

  • 15 марта 2010, 22:46
+
0
Я примерно так же думаю, когда читаю топики Markony: пора браться за паяльник. Тоже никак не соберусь
avatar

yababay

  • 16 марта 2010, 00:11
+
0
Да, товарищи,
столько всего интересного написали тут уже!
avatar

Gangsta

  • 16 марта 2010, 00:25
+
0
Не удивительно, что для Windows хорошо WinAPI ...
Очень полезная инфа !
avatar

Markony

  • 17 марта 2010, 22:10
+
0
Пора мне приковаться к столу и уже начать программить ...
avatar

Markony

  • 17 марта 2010, 22:11

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