求助,android如何使用Jni调用C++的类

2025-05-01 09:48:25
推荐回答(1个)
回答1:

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

[java] view plaincopy
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类
[cpp] view plaincopy
#define LOG_TAG "this is a first JNI test"

#include
#include
#include
#include
#include
#include
#include
#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;
}