自动化零件服务商 - 供应SMC,FESTO,CKD全新正品气动元件
自动化零件服务商 - 供应SMC,FESTO,CKD全新正品气动元件
自动化零件服务商 - 供应SMC,FESTO,CKD全新正品气动元件

前言

前几天我们JNI的使用介绍过《JNI动态注册》和《JNI静态注册》,都是介绍Java的native方法,也就Java调用C或C++中的方法。

今天就介绍C或C++调用Java方法。记录于此,方便自己查阅。

正文

还是在之前基础上改,这里以《JNI动态注册》代码未基础,动态注册很方便和很简单。

功能介绍:模拟计算器加减法,通过native方法传入加或减类型和数值,通过类型判读,JNI中调用Java方法进行计算,再通过native方法返回结果。

Hello.java

  1. package com.biumall.dynamic.one;
  2. public class Hello {
  3.   //1. load Hello.so
  4.   static {
  5.       System.loadLibrary("Hello");
  6.   }
  7.   // 2. define native computer()
  8.   public static native int computer(String type, int a, int b);
  9.   //add
  10.   public int add(int x, int y) {
  11.       return x + y;
  12.   }
  13.   //sub
  14.   public int sub(int x, int y) {
  15.       return x - y;
  16.   }
  17. }
复制

Hello.c

这里依旧以C语言哈

  1. #include <jni.h>
  2. #include <android/log.h>
  3. #include<stdio.h>
  4. #include<string.h>
  5. //LOG_TAG
  6. #define LOG_TAG "from_dynamic_jni_+"
  7. #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
  8. #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
  9. #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
  10. //获取数组大小
  11. #define ARRAY_LENGTH(x) ((int)(sizeof(x) / sizeof((x)[0])))
  12. //定义Hello.java类路径[包名+类名,只不过.换成了/]
  13. //com.biumall.dynamic.one.Hello
  14. #define DYNAMIC_CLASS "com/biumall/dynamic/one/Hello"
  15. //声明方法
  16. int c_add(JNIEnv *env, jclass jclazz, int x, int y);
  17. int c_sub(JNIEnv *env, jclass jclazz, int x, int y);
  18. //native 方法
  19. JNIEXPORT jint JNICALL native_computer(JNIEnv *env, jclass jclazz, jstring type, jint a, jint b) {
  20.   const char *charType = (*env)->GetStringUTFChars(env, type, 0);
  21.   int count;
  22.   if (!strcmp(charType, "-")) {
  23.       count = c_sub(env, jclazz, a, b);
  24.   } else if (!strcmp(charType, "+")) {
  25.       count = c_add(env, jclazz, a, b);
  26.   }
  27.   return count;
  28. }
  29. //jni 调用 java add方法
  30. int c_add(JNIEnv *env, jclass jclazz, int x, int y) {
  31.   jmethodID methodID = (*env)->GetMethodID(env, jclazz, "add", "(II)I");
  32.   jobject object = (*env)->AllocObject(env, jclazz);
  33.   return (*env)->CallIntMethod(env, object, methodID, x, y);
  34. }
  35. //jni 调用 java sub方法
  36. int c_sub(JNIEnv *env, jclass jclazz, int x, int y) {
  37.   jmethodID methodID = (*env)->GetMethodID(env, jclazz, "sub", "(II)I");
  38.   jobject object = (*env)->AllocObject(env, jclazz);
  39.   return (*env)->CallIntMethod(env, object, methodID, x, y);
  40. }
  41. //定义Java和JNI函数的绑定表
  42. // 方法数组,分别为:(方法名[java层定义的],方法签名,函数指针[c层对应替换的方法])
  43. // 可以通过javac和javap 获取 方法签名
  44. JNINativeMethod method_table[] = {
  45.       {"computer", "(Ljava/lang/String;II)I", (void *) native_computer},
  46. };
  47. int registerNativeMethods(JNIEnv *env, const char *className, JNINativeMethod *methods,
  48.                         int methods_size) {
  49.   jclass clazz = NULL;
  50.   //反射Java类
  51.   clazz = (*env)->FindClass(env, className);
  52.   if (NULL == clazz) {
  53.       return JNI_ERR;
  54.   }
  55.   int result = (*env)->RegisterNatives(env, clazz, methods, methods_size);
  56.   LOGD("registerNativeMethods result : %d", result);
  57.   if (result < 0) {
  58.       return JNI_ERR;
  59.   }
  60.   return JNI_OK;
  61. }
  62. JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved ){
  63.   JNIEnv *env = NULL;
  64.   int result = (*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_6);
  65.   LOGD("JNI_OnLoad 1 result : %d", result);
  66.   if(result != JNI_OK){
  67.       return JNI_ERR;
  68.   }
  69.   result = registerNativeMethods(env, DYNAMIC_CLASS, method_table, ARRAY_LENGTH(method_table));
  70.   LOGD("JNI_OnLoad 2 result : %d", result);
  71.   if(result != JNI_OK){
  72.       return JNI_ERR;
  73.   }
  74.   return JNI_VERSION_1_6;
  75. }
复制

动态注册变动的比较少。其实完全可以封装。

上面都有注释,这里就懒得解释了。

参考文章

  1. Android Studio NDK开发-JNI调用Java方法

自动化零件服务商 - 供应SMC,FESTO,CKD全新正品气动元件

相关文章

自动化零件服务商 - 供应SMC,FESTO,CKD全新正品气动元件

暂无评论

none
暂无评论...