导航号,我的单页导航
文章目录

前言

之前学过JNI的动态注册和静态注册,到目前为止,简单的可以依葫芦画瓢了,但对于细节却还有很多的不知道。因此后面慢慢记录一下。方便自己查阅和学习。

正文

如果不知道静态注册和动态注册的使用,请看《JNI静态注册》和《JNI动态注册》,这次只关注详细JNI中方法的前两个参数的解释。

在之前JNI静态注册的基础上,加了一个非静态方法hello2(),然后通过javac和javah一系列操作(怎么用具体看《JNI静态注册》),得到hello和hello2对应的JNI函数声明。

# Java中静态方法hello
public static native String hello();
public native String hello2();

# JNI中对应方法的生命

# 静态hello()
JNIEXPORT jstring JNICALL Java_com_biumall_dynamic_one_Hello_hello
  (JNIEnv *, jclass);
# 非静态hello2()
JNIEXPORT jstring JNICALL Java_com_biumall_dynamic_one_Hello_hello2
  (JNIEnv *, jobject);

这里的hello()方法没有传入其他参数,因此只有两个参数。

参数一

第一个参数都是一样的JNIEnv * env指针。

JNIEnv的类型是一个指针,指向存储全部JNI函数指针的结构。每个函数均可通过JNIEnv参数以固定偏移量进行访问。

推荐看《NDK中jni.h头文件完整内容》查看JNI中定义的函数,至于函数的使用,这里不是重点,暂时略过。

参数二

这个根据本地方法[java中native方法]是否有static而定。

# 静态方法
public static native String hello();
# 非静态方法
public native String hello2();
非静态本地方法

如果是非静态方法,比如上面的hello2(),此时参数二是【对象的引用】,也就是jobject。

# 非静态hello2()
JNIEXPORT jstring JNICALL Java_com_biumall_dynamic_one_Hello_hello2
  (JNIEnv * env, jobject object){
        
  }

当然,如果你想知道类的引用,可以通过GetObjectClass()方法(函数)获取。

jclass clazz = env->GetObjectClass(object);
静态本地方法

如果是静态方法,比如上面的hello(),此时参数二是【类的引用】,也就是jclass。

# 静态hello()
JNIEXPORT jstring JNICALL Java_com_biumall_dynamic_one_Hello_hello
  (JNIEnv * env, jclass jclazz){
    
  }

当然,如果想知道对象的引用,可以通过AllocObject()方法(函数)获取。

jobject object = env->AllocObject(jclazz);
小结

搞懂第二个参数是类引用还是对象引用很重要,因为调用的方法(函数)需要的参数不一样。

比如:

# 获取FieldID需要类引用
jfieldID intFieldID= env->GetFieldID(clazz, "mValue", "I");
# 获取FieldID中的值,需要对象引用
int intValue = env->GetIntField(object, intFieldID);

如果参数传入错误,运行时就会异常。

参考文章

  1. JNI静态注册

  2. JNI动态注册

  3. JNI完全手册

© 版权声明
导航号,我的单页导航

暂无评论

暂无评论...