JNI中调用JAVA各种方法详解
16lz
2021-01-26
总结一下 C 如何 通过 JNI 层调用 Java 的静态和非静态方法
对于:JNIEXPORT void JNICALL Java_com_example_TestNative_sayHello(JNIEnv * env, jobject thiz, jstring paramString)这样一个函数 固定参数: JNIEnv *env:JNIEnv代表java环境,通过*env这个指针,就可以让我们对java层的代码进行操作,比如创建java类的对象,调用java对象的方法,获取java对象的属性等等 这个指针会被JNI传递到本地方法的实现函数中来对java端的代码进行操作。 jobject thiz:分配给这个类的类加载器 函数参数: jstring paramString:这是sayHello函数的具体参数,在外部调用的时候必须给sayHello函数一个参数,如:sayHello(“Hello JNI”); 调用java过程中(重点是调用java中的某些类的某些方法) 主要分下面几个步骤: 1.获取jclass JNIEnv类中有如下几个简单的函数可以取得jclass jclass FindClass(const char* clsName) 根据类名来查找一个类,完整类名 jclass GetObjectClass(jobject obj) 根据一个对象,获取该对象的类 jclass GetSuperClass(jclass obj) 获取一个类的父类 FindClass:根据类名来查找,需要注意的是:这里的类名是某个类的完整路径。 如:String这个类 jclass cls_string= (*env)->FindClass(“java/lang/String”); 在用的时候 需要把 . 换成 / 2.获取类中方法的ID或类属性的ID JNI在jni.h头文件中定义了 jmethodID和 jfieldID类表示Java端的方法和属性 JNIEnv获取相应的jmethodID和 fieldID 的方法: GetMethodID/GetStaticMethodID 获取一个实例的方法ID/一个静态的方法ID GetFieldID/GetStaticMethodID 获取一个实例的域的ID/一个静态的域的ID GetMethodID原型: jmethodID (JNICALL *GetMethodID) (JNIEnv *env, jclass clazz, const char *name, const char *sig); 第一个参数默认的*env 第二个参数是获取到的类 第三个参数是你要获取的某一个方法的名字 第四个参数是“签名”,引用这个签名的作用是对这一函数参数和返回值的描述,对于同一个函数,java是允许对它进行重载的,这时候就必须引入签名来区分他们。 3.调用方法 JNI同样提供了调用java方法的函数 JNIEnv去调用相应java方法的方法有: Call1 2 3 4 5 6 7 8 9 10 11 12 13 | 类型 相应的签名 boolean Z byte B char C short S int I long J float F double D void V object L用 /分隔包的完整类名: Ljava / lang / String ; Array [签名 [ I [ Ljava / lang / Object ; Method (参数 1类型签名 参数 2类型签名··· )返回值类型签名 |
注: 1.object类型的每一个参数最后都得加上”;“ 2.方法参数或者返回值为java中的对象时,签名中必须以“L”加上其路径,不过此路径必须以“/”分开,自定义的对象也使用本规则 例如说 java.lang.String为“java/lang/String”,com.nedu.jni.helloword.Student为”Lcom /nedu/jni/helloword/Student;” 3.方法参数或者返回值为数组类型时,请前加上[ 例如[I表示 int[],[[[D表示 double[][][],即几维数组就加几个[ 实例: C
1 2 3 4 5 6 | void f1 ( ) ( ) V int f2 ( int , long ) ( IJ ) I boolean f3 ( int [ ] ) ( [ I ) B double f4 ( String , int ) ( Ljava / lang / String ; I ) D void f5 ( int , String [ ] , char ) ( I [ Ljava / lang / String ; C ) V byte [ ] f6 ( int , String , String ) ( ILjava / lang / String ; Ljava / lang / String ) [ B |
1 2 3 4 5 6 7 8 | SecureRandom localSecureRandom = new SecureRandom ( ) ; //获取类: jclass jc_SecureRandom = ( * env ) -> FindClass ( env , "java/security/SecureRandom" ) ; //获取构造函数的ID,构造函数的名称都是“ |
b、调用String类的getBytes方法: Java
1 2 3 4 5 6 7 8 9 | //获取类: jclass jc_string = ( * env ) -> FindClass ( env , "java/lang/String" ) ; //获取方法ID: jmethodID jm_getBytes = ( * env ) -> GetMethodID ( env , jc_string , "getBytes" , "()[B" ) ; //参数为空,返回值为byte[] //调用: jbyteArray jb_paramString = ( jbyteArray ) ( * env ) -> CallObjectMethod ( env , paramString , jm_getBytes ) ; |
c、调用Cipher类的 getInstance方法:
1 2 3 4 5 6 7 8 9 10 11 | //获取类: jclass jc_Cipher = ( * env ) -> FindClass ( env , "javax/crypto/Cipher" ) ; //获取方法ID: jmethodID jm_Cipher_getInstance = ( * env ) -> GetStaticMethodID ( env , jc_Cipher , "getInstance" , "(Ljava/lang/String;)Ljavax/crypto/Cipher;" ) ; //参数是一个string, 返回值是一个Cipher //调用: jobject jo_Cipher = ( * env ) -> CallStaticObjectMethod ( env , jc_Cipher , jm_Cipher_getInstance , ( * env ) -> NewStringUTF ( env , "DES" ) ) ; |
实例一:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | /* c/c++ string turn to java jstring */ jstring charToJstring ( JNIEnv* env , const char * pat ) { jclass strClass = ( * env ) -> FindClass ( env , "java/lang/String" ) ; jmethodID ctorID = ( * env ) -> GetMethodID ( env , strClass , " |
实例二
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | #include |
本文出自 0n1y3nd's Blog,转载时请注明出处及相应链接。
本文永久链接: http://0nly3nd.sinaapp.com/?p=277
更多相关文章
- Android面试题总结(五)Android基础篇
- android之网络编程
- Android/java 利用HttpUrlConnection 发送put请求,携带json参数
- Android(安卓)开发学习小结(五)
- android:persistent属性
- 【Android】使用Gallery组件实现循环显示图像
- 阅读Android消息机制源码的随手笔记
- 为何GoogleSearch中可以嵌入EditText?
- Android(安卓)应用权限管理默认开关的修改方法