首页 > 代码库 > 虚拟机下的JNI
虚拟机下的JNI
对于别人写的linux下的jni写的真的不清晰、明了,甚至会出现错误;对于代码重点的就是不会的人用你的代码就可以执行就ok了!!好了,废话不说了,来开始咱们的jni了;
首先咱们得理解一下jni的概念吧: jni(java native interface)java原生接口;对于学习过java的我们并不陌生接口的概念吧,接口就是定义一系列的方法,让其实现类来实现;好了,咱们直接上代码,用代码来解决一切;
第一个程序:对于java类的属性赋值:
首先看看完成后的文件:
首先新建TestInt.java :
public class TestInt{ public native void setInt(int a); public native int getInt(); static{ System.loadLibrary("TestInt"); } public static void main(String args[]){ TestInt testInt = new TestInt(); testInt.setInt(5); System.out.println("你要输出的值为:"+testInt.getInt()); } }
然后进行编译:javac TestInt.java 生成TestInt.class计算机可以读取的二进制文件,依靠此二进制文件生成头文件 TestInt.h
指令为:javah -jni TestInt 生成了TestInt.h文件:其代码如下:
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class TestInt */ #ifndef _Included_TestInt #define _Included_TestInt #ifdef __cplusplus extern "C" { #endif /* * Class: TestInt * Method: setInt * Signature: (I)V */ JNIEXPORT void JNICALL Java_TestInt_setInt (JNIEnv *, jobject, jint); /* * Class: TestInt * Method: getInt * Signature: ()I */ JNIEXPORT jint JNICALL Java_TestInt_getInt (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
咱们可以看到这里有两个方法分别如上图代码所示:
咱们要在写一个c语言代码,来实现对于其方法的实现:说白了,其方法就是接口中要实现的方法:新建一个TestInt.cpp
#include<jni.h> #include"TestInt.h" int b; JNIEXPORT void JNICALL Java_TestInt_setInt (JNIEnv *env, jobject obj, jint a){ b=3+a; } JNIEXPORT jint JNICALL Java_TestInt_getInt (JNIEnv * env, jobject obj){ return b; }
ok!以上代码已经完成,接下来就是要生成动态库了:
g++ -I/usr/java/jdk1.6.0_43/include/linux -I/usr/java/jdk1.6.0_43/include -fpic -shared -o libTestInt.so TestInt.cpp
如果你要是这样写: g++ -fpic -shared -o libTestInt.so TestInt.cpp会抛出如下异常:
TestInt.cpp:1:16: 错误:jni.h:没有那个文件或目录 TestInt.h:15: 错误:expected constructor, destructor, or type conversion before ‘void’ TestInt.h:23: 错误:‘JNIEXPORT’ 没有命名一个类型 TestInt.cpp:5: 错误:expected constructor, destructor, or type conversion before ‘void’ TestInt.cpp:10: 错误:‘JNIEXPORT’ 没有命名一个类型
所以必须要指明jdk的头文件的路径,以及include目录下其他资源文件的路径;
最后一条指令:java Djava.dictionary.path=. TestInt
输出结果:你要输出的值为:8
另外一个程序:关于无返回值字符串的输出程序:
首先也一样将结果目录图片显示出来:
我也不那么多废话了:直接将各个文件的代码复制到页面:
public class TestJni{ public native void print(String context); static{ System.loadLibrary("TestJni"); } }
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class TestJni */ #ifndef _Included_TestJni #define _Included_TestJni #ifdef __cplusplus extern "C" { #endif /* * Class: TestJni * Method: print * Signature: (Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_TestJni_print (JNIEnv *, jobject, jstring); #ifdef __cplusplus } #endif #endif
#include <jni.h> #include "TestJni.h" JNIEXPORT void JNICALL Java_TestJni_print (JNIEnv *env, jobject obj, jstring content){ const jbyte *str=( const jbyte *)(*env)->GetStringUTFChars(env,content,JNI_FALSE); printf("Hello,%s\n",str); (*env)->ReleaseStringUTFChars(env, content, (const char *)str ); }
public class HelloWorld{ public static void main(String args[]){ new HelloWorld(); } public HelloWorld(){ new TestJni().print("yuchao"); } }
各个操作过程第一个程序写的很清楚了,所以这里我就不写了;