本文共 4499 字,大约阅读时间需要 14 分钟。
/*编译:gcc -I/usr/lib/jvm/java-1.7.0-openjdk-amd64/include/ -fPIC -shared -o libnative.so native.c*/#includeJNIDemo.java#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;}
/*编译: 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]); }}调试结果: