JNI之hello world
JNI:Java Native Interface。
在java程序中,我们可以通过JNI实现一些用java语言不便实现的功能。通常有以下几种情况我们需要使用JNI来实现。
- 标准的java类库没有提供你的应用程序所需要的功能,通常这些功能是平台相关的
- 你希望使用一些已经有的类库或者应用程序,而他们并非用java语言编写的
- 程序的某些部分对速度要求比较苛刻,你选择用汇编或者c语言来实现并在java语言中调用他们
话不多说,步骤如下:
1,在java中调用native方法:
public class HelloWorld { public native void displayHelloWorld(); static { System.loadLibrary("hello"); } public static void main(String[] args) { new HelloWorld().displayHelloWorld(); } }
2,编译
javac HelloWorld.java 生成HelloWorld.class文件
3,创建.h文件
这一步中我们要使用javah命令生成.h文件, javah -jni HelloWorld
4,编写本地实现代码
在这部分我们要用C/C++语言实现java中定义的方法,
#include <jni.h> #include "HelloWorld.h" #include <stdio.h> JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj) { printf("Hello world!/n"); return; }
5将c++程序编译成动态库
g++ -I /usr/lib/jvm/java/include -fPIC -shared -o libHelloWorld.so HelloWorld.cpp
则在当前目录生成一个libHelloWorld.so文件
6运行HelloWorld
java HelloWorld
说说我在学习是遇到的问题:
1,在编译动态库时,没有指定jni.h 和jni_md.h (分别在jdk的include目录和 include/linux目录中)
2,紧接着可能也会出现下面的一个错误:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no HelloWorld in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1682)
at java.lang.Runtime.loadLibrary0(Runtime.java:822)
at java.lang.System.loadLibrary(System.java:993)
at HelloWorld.<clinit>(HelloWorld.java:11)
这个错误的原因是LD_LIBRARY_PATH环境变量没有包含当前目录,HelloWorld程序无法找到libHelloWorld.so这个库,解决办法如下:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD; export CLASSPATH=$CLASSPATH:$PWD; java HelloWorld