十大舆情网站,长安网站建设详细教程,得物app公司,品牌网站设计制作哪家好Java中调用native函数传递的参数是Java数据类型#xff0c;到了JNI层需进行数据类型转换#xff0c;基本数据类型是在前面加个j#xff0c;如int——jint#xff0c;应用数据类型除了基本数据类型的数据、Class、String和Throwable外#xff0c;其余所有Java对象的数据…Java中调用native函数传递的参数是Java数据类型到了JNI层需进行数据类型转换基本数据类型是在前面加个j如int——jint应用数据类型除了基本数据类型的数据、Class、String和Throwable外其余所有Java对象的数据类型在JNI中都用jobject表示。//Java层com.xxx.yyy包MyJni.java中的jnitest有三个参数jnitest(String path, String name, MyJni mj);//JNI层对应的函数的后三个参数与jnitest的参数对应com_xxx_yyy_MyJni_jnitest(JNIEnv *env, jobject thiz, jstring path, jstring name, jobject mj);若对象类型都用就object表示就好比是native层的void* 类型一样。第二个参数就object代表Java层的实例对象如果Java层是static函数则这个参数将是jclass表示在调用哪个Java Class的静态函数。JNIEnv介绍JNIEnv是一个与线程相关的代表JNI环境的结构体内部结构如图从上图可知JNIEnv提供了一些JNI系统函数调用Java的函数操作jobejct对象等很多事情每个线程都有一个JNIEnv由于线程相关所以一个线程不能使用另一个线程的JNIEnv结构体。JNIEnv是native函数转换成JNI层函数后有虚拟机传进来的但当后台线程收到一个网络消息且需有native层函数主动回调Java层函数时JNIEnv如何传递这就要用到JavaVM它是虚拟机在JNI层的代表如下//全进程只有一个JavaVM对象可保存且在任何地方都可使用jint JNI_OnLoad(JavaVM* vm, void* reserved);而JavaVM 和 JNIEnv的关系如下调用JavaVM的AttachCurrentThread函数就可得到这个线程的JNIEnv结构体即可在后台回调Java函数。在后台线程退出前需调用JavaVM的DetachCurrentThread函数释放对应的资源。通过JNIEnv操作jobjectJava引用类型除了少数几个外其余在JNI层都会用jobject来表示对象的数据类型操作jobject的本质是操作Java对象的成员变量和成员函数。jfieldID 和 jmethodID 介绍JNI规则中用jfieldID 和 jmethodID表示Java类的成员变量和成员函数可通过JNIEnv的函数得到jfieldID GetFieldID(jclass clazz, const char *name, const char *sig);jmethodID GetMethodID(jclass clazz, const char *name, const char *sig);其中jclass表示Java类name表示成员函数或成员变量的名字sig为这个函数和变量的签名信息。使用方法如下MyJni(JNIEnv *env, jobject mj)......{//先找到com.xxx.yyy.MyJni类在JNI层中对应的jclass实例。jclass myJniInterface env-FindClass(com.xxx.yyy.MyJni);//取出MyJni类中函数jnitest的jMethodID。mMyJniMethodID env-GetMethodID(myJniInterface, jnitest, (Ljava/lang/String;JJ)V);//取出MyJni类中函数jnitest1的jMethodID。mJniTestMethodID env-GetMethodID(myJniInterface, jnitest1,(Ljava/lang/String;Ljava/lang/String;)V);如果每次操作jobject前都去查询jmethodID或jfieldID将会影响程序的运行效率故在初始化时可取出ID并保存起来供后续使用。使用jfieldID 和 jmethodID实例代码如下virtual bool myjni(const char* path, long long lastModified, long long fileSize){jstring pathstr;if ((pathStr mEnv-NewStringUTF(path)) NULL)return;/*调用JNIEnv的CallVoidMethod函数注意CallVoidMethod的参数第一个是MyJni的jobject对象第二个是函数myjni的jmethodID后面是Java中myjni的参数*/mEnv-CallVoidMethod(mClient, mMyJniMethodID, pathStr, lastModified, fileSize);mEnv-DeleteLocalRef(pathStr);return (!mEnv-ExceptionCheck());通过JNIEnv输出CallVoidMethod再把jobject、jMethodID和对应的参数传进去JNI层就能调用Java对象的函数。实际上JNIEnv输出一系列类似CallVoidMethod的函数形式如下NativeType CallMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)其中type对应Java函数的返回值类型例如CallIntMethod、CallVoidMethod等。上面是针对非static函数如果调用Java的static函数则用JNIEnv输出的CallStatic TypeMethod系列函数。通过jfieldID操作jobject的成员变量如下//获得filedID可调用GetField系列函数获取jobject对应的成员变量值nativeType GetField(JNIEnv *env, jobject obj, jfieldID fieldID)//或调用SetField系列函数设置jobject对应的成员变量值void SetField(JNIEnv *env, jobject obj, jfield fieldID, NativeType value)JNI类型签名介绍static JNINativeMethod gMethods[] {......{processFile(Ljava/lang/String;Ljava/lang/String;Landroid/media/MyJni;)V,(void*)com_xxx_yyy_MyJni},......}代码中字符串”(Ljava/lang/String;Ljava/lang/String;Landroid/media/MyJni;)V”是Java中对应函数的签名信息有参数类型和返回值类型共同组成。Java支持函数重载可定义同名但不同参数的函数进根据函数名无法找到具体函数故JNI技术中将参数类型和返回值类型作为函数的签名信息。JNI规范定义的函数签名信息格式(参数1类型标示参数2类型标示...参数n类型标示)返回值类型标示“(Ljava/lang/String;Ljava/lang/String;Landroid/media/MyJni;)V”其中括号内是参数类型的标识最右边是返回值类型的标识void类型对应的标识是V。当参数的类型是引用类型时其格式是“L包名;”其中包名中的“.”换成“/”。Ljava/lang/String表示是一个Java的String类型。