android利用JNI调用C++自定义类

找了好久关于android调用C/C++库的文章,但是始终没有一片是关于android利用jni调用C++自定义类的文章,无奈只好看android的源代码,学习android的图形库的实现,因为它的实现底层也是利用C++的skia库。下面就3个文件来描述。


首先是你在java中的一个类,用于你在应用程序中调用这里取名叫Person类

[java] view plaincopy
  1. package whf.jnitest;  
  2.   
  3. public class Person {  
  4.       
  5.     static  
  6.     {  
  7.         System.loadLibrary("Person");  
  8.     }  
  9.       
  10.     private int mNativePerson;  
  11.       
  12.     public Person()  
  13.     {  
  14.         mNativePerson = init();  
  15.     }  
  16.     protected void finalize()  
  17.     {  
  18.         try {  
  19.             finalizer(mNativePerson);  
  20.         } finally {  
  21.             try {  
  22.                 super.finalize();  
  23.             } catch (Throwable e) {  
  24.                 // TODO Auto-generated catch block  
  25.                 e.printStackTrace();  
  26.             }  
  27.         }  
  28.     }     
  29.     public int getAge()  
  30.     {  
  31.         return native_getAge(mNativePerson);  
  32.     }  
  33.       
  34.     public void setAge(int age)  
  35.     {  
  36.         native_setAge(mNativePerson, age);  
  37.     }  
  38.   
  39.     private native void finalizer(int nPerson);  
  40.     public  native int  add(int a, int b);  
  41.     public  native int  sub(int a, int b);  
  42.     private native int  init();  
  43.       
  44.     private native int  native_getAge(int nPerson);  
  45.     private native void native_setAge(int nPerson, int age);  
  46. }  

然后你的C++文件就如下,我定义为CPerson类

  1. #define LOG_TAG "this is a first JNI test"  
  2.   
  3. #include <stdio.h>  
  4. #include <stdlib.h>  
  5. #include <unistd.h>  
  6. #include <sys/types.h>  
  7. #include <sys/stat.h>  
  8. #include <fcntl.h>  
  9. #include <assert.h>  
  10. #include "jni.h"  
  11. #include "CPerson.h"  
  12.   
  13.   
  14.   
  15.     jint add(JNIEnv *env, jobject obj, jint a, jint b)  
  16.     {  
  17.         return a + b;  
  18.     }  
  19.   
  20.     jint Java_whf_jnitest_Person_sub(JNIEnv *env, jobject obj, jint a, jint b)  
  21.     {  
  22.         return a - b;  
  23.     }  
  24.   
  25.     void Java_whf_jnitest_Person_finalizer(JNIEnv *env, jobject clazz, CPerson *obj)  
  26.     {  
  27.         delete obj;  
  28.     }  
  29.   
  30.     CPerson * Java_whf_jnitest_Person_init(JNIEnv *env, jobject clazz)  
  31.     {  
  32.         CPerson *p = new CPerson();  
  33.         return p;  
  34.     }  
  35.   
  36.     void Java_whf_jnitest_Person_setAge(JNIEnv *env, jobject clazz, CPerson *obj, jint age)  
  37.     {  
  38.         return obj->setAge(age);  
  39.     }  
  40.   
  41.     jint Java_whf_jnitest_Person_getAge(JNIEnv *env, jobject clazz, CPerson *obj)  
  42.     {  
  43.         return obj->getAge();  
  44.     }  
  45.   
  46.     static JNINativeMethod methods[]{  
  47.         {"add""(II)I", (void *)add},  
  48.         {"sub""(II)I", (void *)Java_whf_jnitest_Person_sub},  
  49.         {"finalizer""(I)V", (void *)Java_whf_jnitest_Person_finalizer},  
  50.         {"init""()I", (void *)Java_whf_jnitest_Person_init},  
  51.         {"native_setAge""(II)V", (void *)Java_whf_jnitest_Person_setAge},  
  52.         {"native_getAge""(I)I", (void *)Java_whf_jnitest_Person_getAge},  
  53.     };  
  54.   
  55.     static const char * classPathName = "whf/jnitest/Person";  
  56.   
  57.     static int registerNativeMethods(JNIEnv* env, const char* className,  
  58.         JNINativeMethod* gMethods, int numMethods)  
  59.     {  
  60.         jclass clazz;  
  61.   
  62.         clazz = env->FindClass(className);  
  63.         if (clazz == NULL) {  
  64.             //LOGE("Native registration unable to find class '%s'", className);  
  65.             return JNI_FALSE;  
  66.         }  
  67.         if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {  
  68.             //LOGE("RegisterNatives failed for '%s'", className);  
  69.             return JNI_FALSE;  
  70.         }  
  71.   
  72.         return JNI_TRUE;  
  73.     }  
  74.   
  75.     static int registerNatives(JNIEnv* env)  
  76.     {  
  77.       if (!registerNativeMethods(env, classPathName,  
  78.                      methods, sizeof(methods) / sizeof(methods[0]))) {  
  79.         return JNI_FALSE;  
  80.       }  
  81.   
  82.       return JNI_TRUE;  
  83.     }  
  84.   
  85.     typedef union {  
  86.         JNIEnv* env;  
  87.         void* venv;  
  88.     } UnionJNIEnvToVoid;  
  89.   
  90.     /* This function will be call when the library first be loaded */  
  91.     jint JNI_OnLoad(JavaVM* vm, void* reserved)  
  92.     {  
  93.         UnionJNIEnvToVoid uenv;  
  94.         JNIEnv* env = NULL;  
  95.         //LOGI("JNI_OnLoad!");  
  96.   
  97.         if (vm->GetEnv((void**)&uenv.venv, JNI_VERSION_1_4) != JNI_OK) {  
  98.             //LOGE("ERROR: GetEnv failed");  
  99.             return -1;  
  100.         }  
  101.   
  102.         env = uenv.env;;  
  103.   
  104.         //jniRegisterNativeMethods(env, "whf/jnitest/Person", methods, sizeof(methods) / sizeof(methods[0]));  
  105.   
  106.         if (registerNatives(env) != JNI_TRUE) {  
  107.             //LOGE("ERROR: registerNatives failed");  
  108.             return -1;  
  109.         }  
  110.   
  111.          return JNI_VERSION_1_4;  
  112.     }  


CPerson的声明如下:

  1. #ifndef _CPERSON_H_  
  2. #define _CPERSON_H_  
  3.   
  4. class CPerson  
  5. {  
  6. private:  
  7.     int m_age;  
  8. public:  
  9.     CPerson();  
  10.     int getAge();  
  11.     void setAge(int age);  
  12. };  
  13.   
  14. #endif  

这样一个简单的JNI调用C++自定义类就实现了
原文地址:https://www.cnblogs.com/hzcya1995/p/13318682.html