• 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++自定义类就实现了
  • 相关阅读:
    河南省第十届ACM省赛G:Plumbing the depth of lake
    南洋理工oj 题目92 图像有用区域
    初学欧拉图,知识总结,后续增加
    初学并查集知识总结后续增加
    南阳oj 题目42 一笔画问题
    南阳oj 题目 90 整数划分
    南阳oj题目20吝啬的国度 菜鸟的进阶之路
    南阳oj 题目21 三个水杯
    UVA-540 Team Queue
    HDU-1596 find the safest road
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13318682.html
Copyright © 2020-2023  润新知