java_jni编程全面解析
来源:互联网 发布:淘宝第三层级什么意思 编辑:程序博客网 时间:2024/05/18 04:01
JNI简介
JNI 是 Java Native Interface 的缩写。 Java 本机接口(Java Native Interface,JNI)是一个标准的 Java API,它支持将 Java 代码与使用其他编程语言编写的代码相集成。如果您希望利用已有的代码资源,那么可以使用 JNI 作为您工具包中的关键组件。
下面介绍通过java程序调用C语言编写函数的库函数
宿主机:Ubuntu12.04
java_jdk:openjdk-1.7.0
c编译器:GCC_4.5
1.无参数无返回值的调用
JNI.java
public class JNI { static { //1.load加载C库 System.loadLibrary("native");//libnative.so // } public native static void hello("native"); public static void main(String[] args) { //2.java.hello()-c.hello() //C库函数与java函数的映射 //3.call,调用C库 JNI.hello(); }}
编译 #javac JNI.java
生成头文件#javah -jni JNI
jv_v.c
#include<stdio.h>#include<jni.h>typedef struct { char *name; /* Java里调用的函数名 */ char *signature; /* JNI字段描述符, 用来表示Java里调用的函数的参数和返回值类型 */ void *fnPtr; /* C语言实现的本地函数 */} JNINativeMethod;static const JNINativeMethod methods[] = { {"hello", "()V", (void *)c_hello},//此处分别为java函数名,JNI字段描述符(可参考下方的表 //格),C中的函数指针};javac JNIEXPORT jint JNICALLJNI_OnLoad(JavaVM *jvm, void *reserved){ JNIEnv *env; jclass cls; if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_4)) { return JNI_ERR; /* JNI version not supported */ } cls = (*env)->FindClass(env, "JNI"); if (cls == NULL) { return JNI_ERR; } if((*env)->RegisterNatives(env,cls,methods,1)<0) return JNI_ERR; return JNI_VERSION_1_4;}void c_hello(JNIEnv *env,jobject cls){ printf("hello world\n");}
#gcc -I/usr/lib/jvm/java-1.7.0-openjdk-amd64/include/ -fPIC -shared -o libnative.so jv_v.c
然后将生成的libnative.so库文件放到java文件目录下,使用java命令执行即可
JNI数据类型及JNI字段描述符
有参数有返回值(传入int变量,返回int变量)
JNI2.java
public class JNI2 { static { System.loadLibrary("native"); } public native static int hello(int m); public static void main(String[] args) { System.out.print(JNI2.hello(120)); }}
编译 #javac JNI2.java
生成头文件#javah -jni JNI2
jint_int.c
#include<stdio.h>#include<jni.h>#if 0typedef struct{ char *name;//java char *signature;//JNI void *fnPtr;//}JNINativeMethod;#endif // 0jint JNICALL Java_JNI3_hello (JNIEnv *env, jclass cls, jint m);static const JNINativeMethod methods[] = { {"hello", "(I)I", (void *)c_hello},};JNIEXPORT jint JNICALLJNI_OnLoad(JavaVM *jvm, void *reserved){ JNIEnv *env; jclass cls; if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_4)) { return JNI_ERR; /* JNI version not supported */ } cls = (*env)->FindClass(env, "JNI2"); if (cls == NULL) { return JNI_ERR; } if((*env)->RegisterNatives(env,cls,methods,1)<0) return JNI_ERR; return JNI_VERSION_1_4;}jint c_hello(JNIEnv *env,jobject cls,jint m){ printf("hello world,val = %d\n",m); return 100;}
#gcc -I/usr/lib/jvm/java-1.7.0-openjdk-amd64/include/ -fPIC -shared -o libnative.so jint_int.c
然后将生成的libnative.so库文件放到java文件目录下,使用java命令执行即可
传入字符串返回字符串
public class JNI3 { static { System.loadLibrary("native"); } public native static String hello(String str); public static void main(String[] args) { System.out.print(JNI2.hello("chen")); }}
编译 #javac JNI3.java
生成头文件#javah -jni JNI3
js_s.c
#include<stdio.h>#include<jni.h>#if 0typedef struct{ char *name;//java char *signature;//JNI void *fnPtr;//}JNINativeMethod;#endif //jstring c_hello(JNIEnv *env, jclass cls, jstring str);static const JNINativeMethod methods[] = { {"hello", "(Ljava/lang/String;)Ljava/lang/String;", (void *)c_hello},//此处描述符的 //不同};JNIEXPORT jint JNICALLJNI_OnLoad(JavaVM *jvm, void *reserved){ JNIEnv *env; jclass cls; if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_4)) { return JNI_ERR; /* JNI version not supported */ } cls = (*env)->FindClass(env, "JNI2"); if (cls == NULL) { return JNI_ERR; } if((*env)->RegisterNatives(env,cls,methods,1)<0) return JNI_ERR; return JNI_VERSION_1_4;}jstring c_hello(JNIEnv * env, jclass cls, jstring str) { /*此处需要字符串做转化处理,负责不能直接输出和返回 */ const jbyte *cstr; cstr = (*env)->GetStringUTFChars(env,str,NULL);//将字符串重新转化 if(cstr==NULL) { return NULL; } printf("hello world,c is %s\n",cstr); (*env)->ReleaseStringUTFChars(env,str,cstr);//将字符串重新转化返回 return (*env)->NewStringUTF(env,"from c");}
#gcc -I/usr/lib/jvm/java-1.7.0-openjdk-amd64/include/ -fPIC -shared -o libnative.so js_s.c
然后将生成的libnative.so库文件放到java文件目录下,使用java命令执行即可
传入数组返回int类型
JNI4.java
public class JNI4{ static { System.loadLibrary("native"); } public native static int hello(int[] a); public static void main(String[] args) { int[] a = {1,2,3}; System.out.print(JNI4.hello(a)); }}编译 #javac JNI4.java 生成头文件#javah -jni JNI4
ja_i.c
#include<stdio.h>#include<jni.h>#if 0typedef struct{ char *name;//java char *signature;//JNI void *fnPtr;//}JNINativeMethod;#endif // 0jint c_hello(JNIEnv *env, jclass cls, jintArray arr);static const JNINativeMethod methods[] = { {"hello", "([I)I", (void *)c_hello},};JNIEXPORT jint JNICALLJNI_OnLoad(JavaVM *jvm, void *reserved){ JNIEnv *env; jclass cls; if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_4)) { return JNI_ERR; /* JNI version not supported */ } cls = (*env)->FindClass(env, "JNI4"); if (cls == NULL) { return JNI_ERR; } if((*env)->RegisterNatives(env,cls,methods,1)<0) return JNI_ERR; return JNI_VERSION_1_4;}jint c_hello(JNIEnv *env, jclass cls, jintArray arr){ jint *carr; jint i,sum = 0; carr = (*env)->GetIntArrayElements(env,arr,NULL); if(carr==NULL) return 0; for(i=0;i<(*env)->GetArrayLength(env,arr);i++) { sum = sum+carr[i]; } (*env)->ReleaseIntArrayElements(env,arr,carr,0); return sum;}
#gcc -I/usr/lib/jvm/java-1.7.0-openjdk-amd64/include/ -fPIC -shared -o libnative.so ja_i.c
然后将生成的libnative.so库文件放到java文件目录下,使用java命令执行即可
传入数组参数返回数组
public class JNI5 { static { System.loadLibrary("native"); } public native static int[] hello(int[] a); public static void main(String[] args) { int[] a = {1,2,3}; int[] b = null; b = JNI5.hello(a); for(int i =0;i<b.length;i++) System.out.print(b[i]); }}
编译 #javac JNI5.java
生成头文件#javah -jni JNI5
ja_a.c
#include<stdio.h>#include<jni.h>#include<stdlib.h>#if 0typedef struct{ char *name;//java char *signature;//JNI void *fnPtr;//}JNINativeMethod;#endif // 0jintArray c_hello(JNIEnv *env, jclass cls, jintArray arr);static const JNINativeMethod methods[] = { {"hello", "([I)[I", (void *)c_hello},};JNIEXPORT jint JNICALLJNI_OnLoad(JavaVM *jvm, void *reserved){ JNIEnv *env; jclass cls; if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_4)) { return JNI_ERR; /* JNI version not supported */ } cls = (*env)->FindClass(env, "JNI5"); if (cls == NULL) { return JNI_ERR; } if((*env)->RegisterNatives(env,cls,methods,1)<0) return JNI_ERR; return JNI_VERSION_1_4;}jintArray c_hello(JNIEnv *env, jclass cls, jintArray arr){ jint *carr; jint *oarr; jintArray rarr; jint i,n = 0; carr = (*env)->GetIntArrayElements(env,arr,NULL);//数组转化 if(carr==NULL) return 0;//转化失败 n =(*env)->GetArrayLength(env,arr);//获取传入数组长度 oarr = malloc(sizeof(jint)*n);//分配内存空间 if(oarr==NULL) { (*env)->ReleaseIntArrayElements(env,arr,carr,0);//释放 return 0; } for(i=0;i<n;i++) { oarr [i] = carr[n-i-1];//逆序转化 } (*env)->ReleaseIntArrayElements(env,arr,carr,0); rarr = (*env)->NewIntArray(env,n); if(rarr==NULL) { return 0; } (*env)->SetIntArrayRegion(env,rarr,0,n,oarr); free(oarr);//释放内存空间 return rarr;}
#gcc -I/usr/lib/jvm/java-1.7.0-openjdk-amd64/include/ -fPIC -shared -o libnative.soja_a.c
然后将生成的libnative.so库文件放到java文件目录下,使用java命令执行即可
- java_jni编程全面解析
- Java_JNI
- java_jni调用
- java_jni参数调用
- 全面解析Server对象
- const全面解析
- Google 广告 全面解析
- 全面解析磁盘分区格式
- 全面解析JDBC(一)
- 全面解析JDBC
- 全面解析JDBC
- 全面解析jdbc
- 全面解析JDBC
- 全面解析JDBC
- CMMI 全面解析
- 全面解析 JDBC
- 全面解析Server对象
- 全面解析Server对象
- C++ stl---string类里常用的成员函数
- Mongodb用户安全认证
- 在数组中进行图形绘制
- 小试一下
- Java读取TXT文件的方法
- java_jni编程全面解析
- servlet3.0处理文件上传
- TightVNC2.8.5在VS2010下编译和错误解决
- UVA 10405最长公共子序列
- java实现约瑟夫环
- 警告: Could not find action or result
- 小约分
- Java中getResourceAsStream的用法
- 深入理解K-Means聚类算法