JNI-Java和C之间通信

来源:互联网 发布:互联网金融 算法 编辑:程序博客网 时间:2024/05/17 22:38


主要通过一些方法、函数来介绍下Java和C之间通信

Java通过JNI调用C函数实例代码

char*   Jstring2CStr(JNIEnv*   env,   jstring   jstr){ char*   rtn   =   NULL; //c调用java中的类的方法 jclass   clsstring   =   (*env)->FindClass(env,"java/lang/String"); jstring   strencode   =   (*env)->NewStringUTF(env,"GB2312"); jmethodID   mid   =   (*env)->GetMethodID(env,clsstring,   "getBytes",   "(Ljava/lang/String;)[B"); jbyteArray   barr=   (jbyteArray)(*env)->CallObjectMethod(env,jstr,mid,strencode); // String .getByte("GB2312"); jsize   alen   =   (*env)->GetArrayLength(env,barr); jbyte*   ba   =   (*env)->GetByteArrayElements(env,barr,JNI_FALSE); if(alen   >   0) {  rtn   =   (char*)malloc(alen+1);         //"\0"  memcpy(rtn,ba,alen);  rtn[alen]=0; } (*env)->ReleaseByteArrayElements(env,barr,ba,0);  // return rtn;}/** * env代表的是   虚拟机C语言实现的结构体指针 * obj代表的是   当前调用的对象 * */JNIEXPORT jint JNICALL Java_com_justsy_ndkpassdata_PassDataToC_add  (JNIEnv * env, jobject obj, jint x, jint y){//java中int类型和c中的int类型占用的内存空间一样,可以直接返回return x+y;}//传递String类型的参数JNIEXPORT jstring JNICALL Java_com_justsy_ndkpassdata_PassDataToC_sendMsgToC  (JNIEnv * env, jobject obj, jstring jstr){//jstring转化为c的Char *类型char* cstr = Jstring2CStr(env,jstr);LOGD("c char %s",cstr);char marr[7] = {' ','h','e','l','l','o','\0'};//\0结束strcat(cstr,marr);//拷贝LOGD("c char add arr is %s",cstr);return (*env)->NewStringUTF(env,cstr);}//传递int数组JNIEXPORT jintArray JNICALL Java_com_justsy_ndkpassdata_PassDataToC_sendArrayToC  (JNIEnv * env, jobject obj, jintArray carr){//arr lengthint arrLen = (*env)->GetArrayLength(env,carr);//返回的是array的首地址jint* intarr = (*env)->GetIntArrayElements(env,carr,0);int i = 0;for(;i<arrLen;i++){*(intarr+i) += 10;}return carr;}/** * java静态方法对应的c函数 * jclass代表的是调用的类 * */JNIEXPORT jint JNICALL Java_com_justsy_ndkpassdata_PassDataToC_sub  (JNIEnv * env, jclass clazz, jint x, jint y){return x-y;}

对应的Java native方法为

public native String sendMsgToC(String msg);public native int[] sendArrayToC(int[] arr);public native static int sub(int x,int y);

C通过JNI调用Java方法实例代码

/* * Class:     tu_bb_ndk_DataProvider * Method:    callmethod1 * Signature: ()V */JNIEXPORT void JNICALL Java_tu_bb_ndk_DataProvider_callmethod1  (JNIEnv * env, jobject obj){//获取jclass,对应java类的class对象jclass clazz = (*env)->FindClass(env, "tu/bb/ndk/DataProvider");if(clazz==0){LOGD("clazz can't get");return;}//获取方法ID,提供jclass、方法名和方法签名,方法签名可以jdk提供的javap -s 类全名 命令得到jmethodID method1ID = (*env)->GetMethodID(env, clazz, "sayHelleFromC", "()V");if(method1ID==0){LOGD("method1ID can't get");return;}//调用无参方法(*env)->CallVoidMethod(env, obj, method1ID);}/* * Class:     tu_bb_ndk_DataProvider * Method:    callmethod2 * Signature: ()V */JNIEXPORT void JNICALL Java_tu_bb_ndk_DataProvider_callmethod2  (JNIEnv * env, jobject obj){jclass clazz = (*env)->FindClass(env, "tu/bb/ndk/DataProvider");if(clazz==0){LOGD("clazz can't get");return;}jmethodID method2ID = (*env)->GetMethodID(env, clazz, "add", "(II)I");if(method2ID==0){LOGD("method2ID can't get");}//调用有参方法,(*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...),可变参数jint result = (*env)->CallIntMethod(env, obj, method2ID, 1,2);LOGD("result %d",result);}/* * Class:     tu_bb_ndk_DataProvider * Method:    callmethod3 * Signature: ()V */JNIEXPORT void JNICALL Java_tu_bb_ndk_DataProvider_callmethod3  (JNIEnv * env, jobject obj){jclass clazz = (*env)->FindClass(env, "tu/bb/ndk/DataProvider");if(clazz==0){LOGD("clazz can't get");return;}jmethodID method3ID = (*env)->GetMethodID(env, clazz, "getMsgFromC", "(Ljava/lang/String;)V");if(method3ID==0){LOGD("method3ID can't get");return;}(*env)->CallVoidMethod(env, obj, method3ID, (*env)->NewStringUTF(env,"HelloWorld"));}JNIEXPORT void JNICALL Java_tu_bb_ndk_DataProvider_callmethod4  (JNIEnv * env, jobject obj){jclass clazz = (*env)->FindClass(env, "tu/bb/ndk/DataProvider");if(clazz==0){LOGD("clazz can't get");return;}jmethodID  method4ID =  (*env)->GetStaticMethodID(env, clazz, "getStaticMsgFromC", "(Ljava/lang/String;)V");if(method4ID==0){LOGD("method4ID can't get");return;}//调用静态的Java方法,第二个参数改为jclass对象,这里还是很好理解的(*env)->CallStaticVoidMethod(env, clazz, method4ID, (*env)->NewStringUTF(env,"static hello"));}

对应的Java native方法

public void sayHelleFromC(){System.out.println("Hello World");} public int add(int x,int y){return x+y;}public void getMsgFromC(String msg){System.out.println("msg:"+msg);}public static void getStaticMsgFromC(String msg){System.out.println("msg:"+msg);}public native void callmethod1();public native void callmethod2();public native void callmethod3();public native void callmethod4();

注:所有的java和c数据类型之间的转换均可参考jni.h头文件中的定义,jni.h位于android-ndk-r7b\platforms\android-9\arch-arm\usr\include下



原创粉丝点击