找了好久关于android调用C/C++库的文章,但是始终没有一片是关于android利用jni调用C++自定义类的文章,无奈只好看android的源代码,学习android的图形库的实现,因为它的实现底层也是利用C++的skia库。下面就3个文件来描述。
然后你的C++文件就如下,我定义为CPerson类
这样一个简单的JNI调用C++自定义类就实现了
首先是你在java中的一个类,用于你在应用程序中调用这里取名叫Person类
- package whf.jnitest;
- public class Person {
- static
- {
- System.loadLibrary("Person");
- }
- private int mNativePerson;
- public Person()
- {
- mNativePerson = init();
- }
- protected void finalize()
- {
- try {
- finalizer(mNativePerson);
- } finally {
- try {
- super.finalize();
- } catch (Throwable e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- public int getAge()
- {
- return native_getAge(mNativePerson);
- }
- public void setAge(int age)
- {
- native_setAge(mNativePerson, age);
- }
- private native void finalizer(int nPerson);
- public native int add(int a, int b);
- public native int sub(int a, int b);
- private native int init();
- private native int native_getAge(int nPerson);
- private native void native_setAge(int nPerson, int age);
- }
然后你的C++文件就如下,我定义为CPerson类
- #define LOG_TAG "this is a first JNI test"
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <assert.h>
- #include "jni.h"
- #include "CPerson.h"
- jint add(JNIEnv *env, jobject obj, jint a, jint b)
- {
- return a + b;
- }
- jint Java_whf_jnitest_Person_sub(JNIEnv *env, jobject obj, jint a, jint b)
- {
- return a - b;
- }
- void Java_whf_jnitest_Person_finalizer(JNIEnv *env, jobject clazz, CPerson *obj)
- {
- delete obj;
- }
- CPerson * Java_whf_jnitest_Person_init(JNIEnv *env, jobject clazz)
- {
- CPerson *p = new CPerson();
- return p;
- }
- void Java_whf_jnitest_Person_setAge(JNIEnv *env, jobject clazz, CPerson *obj, jint age)
- {
- return obj->setAge(age);
- }
- jint Java_whf_jnitest_Person_getAge(JNIEnv *env, jobject clazz, CPerson *obj)
- {
- return obj->getAge();
- }
- static JNINativeMethod methods[]{
- {"add", "(II)I", (void *)add},
- {"sub", "(II)I", (void *)Java_whf_jnitest_Person_sub},
- {"finalizer", "(I)V", (void *)Java_whf_jnitest_Person_finalizer},
- {"init", "()I", (void *)Java_whf_jnitest_Person_init},
- {"native_setAge", "(II)V", (void *)Java_whf_jnitest_Person_setAge},
- {"native_getAge", "(I)I", (void *)Java_whf_jnitest_Person_getAge},
- };
- static const char * classPathName = "whf/jnitest/Person";
- static int registerNativeMethods(JNIEnv* env, const char* className,
- JNINativeMethod* gMethods, int numMethods)
- {
- jclass clazz;
- clazz = env->FindClass(className);
- if (clazz == NULL) {
- //LOGE("Native registration unable to find class '%s'", className);
- return JNI_FALSE;
- }
- if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
- //LOGE("RegisterNatives failed for '%s'", className);
- return JNI_FALSE;
- }
- return JNI_TRUE;
- }
- static int registerNatives(JNIEnv* env)
- {
- if (!registerNativeMethods(env, classPathName,
- methods, sizeof(methods) / sizeof(methods[0]))) {
- return JNI_FALSE;
- }
- return JNI_TRUE;
- }
- typedef union {
- JNIEnv* env;
- void* venv;
- } UnionJNIEnvToVoid;
- /* This function will be call when the library first be loaded */
- jint JNI_OnLoad(JavaVM* vm, void* reserved)
- {
- UnionJNIEnvToVoid uenv;
- JNIEnv* env = NULL;
- //LOGI("JNI_OnLoad!");
- if (vm->GetEnv((void**)&uenv.venv, JNI_VERSION_1_4) != JNI_OK) {
- //LOGE("ERROR: GetEnv failed");
- return -1;
- }
- env = uenv.env;;
- //jniRegisterNativeMethods(env, "whf/jnitest/Person", methods, sizeof(methods) / sizeof(methods[0]));
- if (registerNatives(env) != JNI_TRUE) {
- //LOGE("ERROR: registerNatives failed");
- return -1;
- }
- return JNI_VERSION_1_4;
- }
- #ifndef _CPERSON_H_
- #define _CPERSON_H_
- class CPerson
- {
- private:
- int m_age;
- public:
- CPerson();
- int getAge();
- void setAge(int age);
- };
- #endif
这样一个简单的JNI调用C++自定义类就实现了