JNI:取得Java属性和设置Java属性值

JAVA乐园

共 1467字,需浏览 3分钟

 ·

2022-03-04 01:00

1. 取得Java属性/设定Java属性值

  • 获得了相应属性的jfieldID之后,就可以使用

SetFieldGetFieldSetStaticFieldGetStaticField

等函数来对Java属性进行操作了。

  • 类实例方法

Set/GetBooleanFieldSet/GetByteFieldSet/GetDoubleFieldSet/GetFloatFieldSet/GetIntFieldSet/GetLongFieldSet/GetShortFieldSet/GetObjectField
  • 类静态方法

Set/GetStaticBooleanFieldSet/GetStaticByteFieldSet/GetStaticDoubleFieldSet/GetStaticFloatFieldSet/GetStaticIntFieldSet/GetStaticLongFieldSet/GetStaticShortFieldSet/GetStaticObjectField
  • 怎样获取数组的属性呢?

可以使用GetObjectField来获取数组类型的属性。不过JNI提供了一系列方法获取数组的属性,后续介绍。

2. 案例

在C/C++中修改Java中的属性

package com.omg;
public class TestNative {
public int number;
public native void sayHello();
}

C++代码

jclass clazz_TestNative = env->GetObjectClass( obj);jfieldID id_number = env->GetFieldID(clazz_TestNative, "number", "I");jint number = env->GetIntFiled(obj, id_number);count << number << endl;env->SetIntField(obj, id_number, 100L);

3. Java方法调用

  • JNIEnv提供了众多的 CallMethod 与 CallStaticMethod,还有CallNonvirtualMethod函数。需要通过GetMethodID取得相应方法的jmethodID来传入上述函数的参数中。

  • 调用实例方法的三种形式

CallMethod( jobject obj, jmethodID id, ...);CallMethodV( jobject obj, jmethodID id, va_list lst);CallMethodA( jobject obj, jmethodID id, jvalue* v);

第一种是最常用的方式

第二种是当调用这个函数的时候,有一个指向参数表的va_list变量时使用(不常用)

第三种是当调用这个函数的时候,有一个指向jvalue或者jvalue数组的指针时使用

调用静态方法的三种形式

CallStaticMethod( jclass clazz, jmethodID id, ...);CallStaticMethodV( jclass clazz, jmethodID id, va_list lst);CallStaticMethodA( jclass clazz, jmethodID id, jvalue* v);

伪代码

java:public boolean function(int i, double d, char c){     //......}
Cenv->CallBooleanMethod(obj, id_function, 100L, 1.11, L'3')
jvalue * args = new jvalue[3];args[0].i = 100L;args[1].d = 3.44;args[2].c = L'3';env->CallBooleanMethod( obj, id_function, args);delete [] args;

4. 案例

在C/C++中代用Java中的方法

Java代码

package com.omg;
public class TestNative { public max(double num1, double num2){ return num1 > num2 ? num1 : num2;    }}

C++代码

jclass clazz_TestNative = env->GetObjectClass( obj );jmethodID id_max = env->GetMetodID( clazz_TestNative, obj, "(DD)D");jdouble maxVal = env->GetDoubleMethod(obj, id_max, 2.1, 3.14);cout << maxVal << endl;

5. CallNonvirtualMethod

有如下Java代码

public class Father {
public void function(){        System.out.println("Father function");        } }    public class Child extends Father { public void function(){ System.out.println("Child function"); }
}

想想这段Java代码调用的是哪个类的方法?

Father p = new Child();p.function();

如果想调用父类的function是没有办法的

有如下C++代码

class Father {
public:    void function(){        cout << "Father function" < }
}
  class Child : public Father { public: void function(){        cout << "Child function" < }
}

想想这段代码调用的是哪个类的成员函数?(调用的是父类的函数)

Father* p = new Child();p->function();

C++有虚函数的概念,修改一下父类加一个 virtual


class Father {
public: virtual void function(){     cout << "Father function" <<endl; }
}
class Child : public Father {
public: void function(){          cout << "Child function" <<endl; }
}


再想想这段代码调用的是哪个类的成员函数?(调用的是子类的函数)


Father* p = new Child();p->function();

在Java语言中,所有的函数都是虚函数

  • 在JNI中定义了CallNonvirtualMethod就能实现子类对象调用父类方法的功能,如果想要调用一个对象的父类的方法,而不是子类的重写(over write)的方法的话,就可以使用CallNonVirtualMethod

  • 要使用CallNonVirtualMethod,首先要取得父类及要调用的父类的方法的jmethodID。然后传入到这个函数就能通过子类对象调用被重写(over write)的父类的方法

5. 案例

package com.omg;

public class Father {
public void function() {      System.out.println("Father function"); }
}


package com.omg;

public class Child extends Father {
public void function() {        System.out.println("Child function"); }
}

测试

Java定义成员变量

public Father p = new Child();

C++代码

jclass clazz_TestNative = env->GetObjectClass( obj );jfieldID id_p = env->GetFieldID(clazz_TestNative, "p", "Lcom/omg/Father;");jobject p = env->GetObjectField(obj, id_p);
jclass clazz_Father = env->FindClass( "Lcom/omg/Father;" );jmethodID id_Father_function = env->GetMethodID(clazz_Father, "function", "()V");
env->CallVoidMethod(p, id_Father_function);
env->CallNonvirtualVoidMethod(p, clazz_Father, id_Father_function);

分享&在看

浏览 37
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报