jni-jobject操作对象

前言

jni中除了基本数据类型和数组之外,都是jobject类型的变量。jni提供了一系列的方法来操作jobject。 
下面的示例都是根据TestObject.java来进行的。

public class TestObject {

  private String firstName;
  private String secondName;

  public TestObject(String firstName, String secondName) {
    this.firstName = firstName;
    this.secondName = secondName;
  }

  public String getResult() {
    return String.format("%1$s-=-%2$s", firstName, secondName);
  }
}

判断对象类型

IsInstanceOf(env, jobj, jclass)可以用来判断jobject是否是某个jclass类型。

jclass jTestObject = (*env)->FindClass(env, "com/mislead/testjni/TestObject");

if(jTestObject==NULL)
{
    LOGE("cannot found class:com/mislead/testjni/TestObject");
    return NULL;
}

if((*env)->IsInstanceOf(env, obj, jTestObject))
{

}

调用对象方法

  • GetObjectMethodID(env, jclass, methodName, signature)获取到方法id。
  • CallObjectMethod(env, jobject, methodID)来调用方法,或者获取结果。
// getResult() method
// first get method id by GetMethodID(JNIEnv, jclass, methodName, methodSignature)
jmethodID jmID=(*env)->GetMethodID(env, jTestObject, "getResult", "()Ljava/lang/String;");
// call method
return (*env)->CallObjectMethod(env, obj, jmID);

关于Signature

如果细心会发现我们在生成的jni头文件,函数前的注释部分都有Signature,你可以参考写法。下面是一些说明: 
方法的Signature是由方法的参数和返回值的类型共同构成的,下面是他们的结构: 
“(argument-types)return-type” 
其中Java程序中参数类型和其对应的值如下:

Signature  Java中的类型 
Z       boolean 
B       byte 
C       char 
S       short 
I        int 
J        long 
F       float 
D       double 
L fully-qualified-class;   fully-qualified-class 
   
[ type  type[] 
   
( arg-types ) ret-type  method type

一个Java类的方法的Signature可以通过javap命令获取: 
javap -s -p Java类名

生成一个对象

  • FindClass(env, className)得到想要的jclass。
  • GetObjectMethodID(env, jclass, "<init>", signature)获取到构造方法的ID。类的构造方法名字统一为<init>,默认无参数的signature为()V
/*
 * Class:     com_mislead_testjni_TestJni
 * Method:    testCreateObject
 * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 */
                  JNIEXPORT jstring JNICALL Java_com_mislead_testjni_TestJni_testCreateObject
        (JNIEnv *env, jobject jobj, jstring first, jstring second)
{
    //first, create a TestObject
    jclass jTestObject = (*env)->FindClass(env, "com/mislead/testjni/TestObject");
    // get construct method id
    jmethodID construct = (*env)->GetMethodID(env, jTestObject, "<init>", "(Ljava/lang/String;Ljava/lang/String;)V");

    jobject obj=(*env)->NewObject(env, jTestObject, construct, first, second);

    return callGetResult(env, obj);
}

获取对象的属性

  • GetObjectFieldID(env, jclass, fieldName, signature)获取fieldID。
  • GetObjectField(env, jobject, fieldID)获取到属性值。
jclass jcls=(*env)->GetObjectClass(env, obj);

jfieldID fid=(*env)->GetFieldID(env, jcls, "firstName", "Ljava/lang/String;");

jstring firstName=(*env)->GetObjectField(env, obj, fid);

静态方法和属性

调用静态方法:   
就是将第二步和第三步调用的方法改为对应的: 
GetStaticMethodID获取对应的静态方法的ID 
CallStaticIntMethod调用静态方法 
获取静态属性: 
使用GetStaticFieldID>

猜你喜欢

转载自blog.csdn.net/jisuanji198509/article/details/81210727