博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JNI-Java访问C库
阅读量:4125 次
发布时间:2019-05-25

本文共 4499 字,大约阅读时间需要 14 分钟。

JNI字段描述符
  • 用"["表示数组,比如"int []"表示为"[I"
  • 对于类,要用全称"L包.子包.类名;"(前面有"L",后面有";"),比如"Ljava/lang/String;"
  • 除String类外,其他的类都用Object表示,即"Ljava/lang/Object;"
native.c
/*编译:gcc -I/usr/lib/jvm/java-1.7.0-openjdk-amd64/include/ -fPIC -shared -o libnative.so native.c*/#include 
#include
#include
//usr/lib/jvm/java-1.7.0-openjdk-amd64/include/jni.h#if 0typedef struct { char *name; /* java里调用的函数名 */ char *signature; /* JNI字段描述符,用来表示Jave里调用的函数的参数和返回值类型 */ void *fnPtr; /* C语言实现的本地函数 */}JNINativeMethod;#endif/*注意:C函数比Java里的声明多2个参数: (JNIEnv *env, jclass cls)*/void c_hello(JNIEnv *env, jobject cls){ printf("hello world!\n");}/* 形参:int 返回值:int*/jint c_myprintf(JNIEnv *env, jobject cls, jint m){ printf("hello world! %d\n",m); return 100;}/* 形参:String 返回值:String*/jstring JNICALL c_display_string(JNIEnv *env, jobject cls, jstring str){ //printf("this is c : %s\n",str); //return "return from C"; const jbyte *cstr; cstr = (*env)->GetStringUTFChars(env, str, NULL); if (cstr == NULL) { return NULL; /* OutOfMemoryError already thrown */ } printf("get string from java:%s\n", cstr); (*env)->ReleaseStringUTFChars(env, str, cstr); return (*env)->NewStringUTF(env, "return from c");}/* 形参:传入数组 返回值:int*/jint JNICALL c_display_data(JNIEnv *env, jobject cls, jintArray arr){ jint *carr; jint i, sum = 0; carr = (*env)->GetIntArrayElements(env, arr, NULL); if (carr == NULL) { return 0; /* exception occurred */ } for (i = 0; i < (*env)->GetArrayLength(env,arr); i++) { sum += carr[i]; } (*env)->ReleaseIntArrayElements(env, arr, carr, 0); return sum;}/* * Class: JNIDemo * Method: display_array * Signature: ([I)[I * * 形参:传入数组 * 返回值:输出数组 */jintArray JNICALL c_display_array(JNIEnv *env, jobject cls, jintArray arr){ jint *carr; jint *oarr; jintArray rarr; jint i, n = 0; carr = (*env)->GetIntArrayElements(env, arr, NULL); if (carr == NULL) { return 0; /* exception occurred */ } 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-1-i]; } /*Creates an jint array with thegiven length.*/ rarr = (*env)->NewIntArray(env,n); if(rarr == NULL) { (*env)->ReleaseIntArrayElements(env, arr, carr, 0); return 0; } /*Copies the contents of primitive arrays to or from a preallocated C buffer. void (JNICALL *SetIntArrayRegion) (JNIEnv *env, jintArray array, jsize start, jsize len, const jint *buf); */ (*env)->SetIntArrayRegion(env,rarr,0,n,oarr); (*env)->ReleaseIntArrayElements(env, arr, carr, 0); free(oarr); return rarr;}/* 定义一个映射数组JNINativeMethod[]可以注册多个本地函数*/static const JNINativeMethod methods[] = { {"hello","()V",(void *)c_hello}, {"myprintf","(I)I",(void *)c_myprintf}, {"display_string","(Ljava/lang/String;)Ljava/lang/String;",(void *)c_display_string}, {"display_data","([I)I",(void *)c_display_data}, {"display_array","([I)[I",(void *)c_display_array},};/* 只要java 加载库System.loadLibrary 就会执行该函数 */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, "JNIDemo"); if (cls == NULL) { return JNI_ERR; } /* 建立联系 java<--->c*/ if((*env)->RegisterNatives(env,cls,methods,5) < 0) return JNI_ERR; return JNI_VERSION_1_4;}
JNIDemo.java
/*编译:		javac JNIDemo.java		export LD_LIBRARY_PATH=.		java JNIDemo自动生成字段描述符:		javac JNIDemo.java		javah -jni JNIDemo*/public class JNIDemo {	/* 静态代码块,加载库只执行一次 */		static {			/* 1. load 加载libnative.so */			System.loadLibrary("native");/* libnative.so */		}	//public native static void hello();//声明	public native void hello();//声明	public native int myprintf(int m);	public native String display_string(String str);	public native int display_data(int a[]);	public native int[] display_array(int a[]);	public static void main(String args[]){		JNIDemo d = new JNIDemo();		int a[] = {1, 2, 3, 4, 5};		int b[] = null;		int i;		/* 2. java <--> c 建立映射关系 */		/* 3.调用 */		d.hello();		System.out.println(d.myprintf(123));		System.out.println(d.display_string("this is java jni demo"));		System.out.println(d.display_data(a));		b = d.display_array(a);		for(i = 0; i < b.length; i++)			System.out.println(b[i]);	}}
调试结果:
                                                                                                                          参考学习韦东山java视频整理
                                                                                                                                              2017-07-25
你可能感兴趣的文章
语音信号处理-梅尔倒频谱系数MFCC
查看>>
梅尔倒谱系数实现-MFCC
查看>>
海量搜索服务架构搭建1-基于spring的搜索服务
查看>>
海量搜索服务架构搭建2-SolrCloud集群搭建
查看>>
hadoop学习记录1-基本原理
查看>>
hadoop学习记录2-Hadoop安装配置
查看>>
一部电影晓生活-韩国
查看>>
并发编程实战1-多线程的周期、实现方式和意义
查看>>
并发编程实战2-Synchronized原理与使用
查看>>
并发编程实战3-单例模式与线程安全性问题
查看>>
并发编程实战4-自旋锁,死锁,以及锁重入详解
查看>>
Java中的读写锁
查看>>
并发编程实战6-线程之间的通信-深入解析Condition源码
查看>>
并发编程实战7-线程之间的通信2-join加塞线程
查看>>
并发编程实战8-ThreadLocal原理与使用-线程局部变量
查看>>
并发编程实战9-Java中的并发工具类
查看>>
并发编程实战10-多线程中的任务分解机制ForkJoinPool详解
查看>>
并发编程实战11-并发容器CopyOnWriteArrayList
查看>>
并发编程实战13-同步中的四种锁synchronized、ReentrantLock、ReentrantReadWriteLock、StampedLock
查看>>
并发编程实战14-LongAdder统计加法器-计数器jdk8
查看>>