zoukankan      html  css  js  c++  java
  • JNI笔记之 初体验

    Java Native Interface提供了java与c语言写的代码之间互相调用的方式。在c语言方面jni.h中声明了许多的类型和方法,有很多java的数据类型和c语言类型的转换方法函数。

    java里的int,String,byte[]等对应于C方面的jint,jstring,jbyteArray.int可以直接赋给jint型的变量。

    Java的String和C++的string是不能对等起来的,所以jstring的操作较为繁琐,通常可转为c里面的char *,有两种方式,先上简单的:

    JNIEXPORT jstring JNICALL Java_Prompt_getLine(JNIEnv*env,jobject obj,jstring prompt)
      
      {
      
      const char*str;
      
      str=env->GetStringUTFChars(prompt,false);
      
      if(str==NULL){
      
      return NULL;/*Out Of Memory Error already thrown*/
       
      }
      
      std::cout<<str<<std::endl;
      
      env->ReleaseStringUTFChars(prompt,str);
      
      
      char*  tmpstr="return string succeeded";
      
      jstring rtstr=env->NewStringUTF(tmpstr);
      
      return rtstr;
      
      }
      
      在上面的例子中,作为参数的prompt不能直接被C++程序使用,先做了如下转换
      str=env->GetStringUTFChars(prompt,false);
      将jstring类型变成一个char*类型。
      
      返回的时候,要生成一个jstring类型的对象,也必须通过如下命令,
      jstringrtstr=env->NewStringUTF(tmpstr);
      
      这里用到的GetStringUTFChars和NewStringUTF都是JNI提供的处理String类型的函数,还有其他的函数这里就不一一列举了。

    数组操作有:jint*carr;  
      carr=env->GetIntArrayElements(arr,false);  

      env->ReleaseIntArrayElements(arr,carr,0);

    env->SetIntArrayRegion(jintarr,i,num,&tmp);//修改jintarr的从i位置开始的连续num个数为tmp里的值

    注意上边的env在C++代码里是一个指向java虚拟机(JVM)的一个指针,(不知说的对不对,咱也不是专家,这也许在android里有些区别,android用了很多年的Dalvik虚拟机,每个app为一个子进程,通过NDK写的动态链接库执行时与java的代码执行在一个进程里),在c语言里面env是个二级指针,使用时形如:

    (*env)->SetIntArrayRegion(env,jintarr,i,1,&tmp);参数里面需要传递env。

    c中调用java中的函数的方式,类似反射机制:

    char* classname="com/example/calculate";//类名,类中有个方法add(int a,int b)

    jclass clazz;

    clazz=(*env)->FindClass(env,classname);

    if(clazz==0) //printf or LOGI("Can't find clazz");return;

    jmethodID java_method=(*env)->GetMethodID(env,clazz,"add","(II)I");//方法名为add,签名为(II)I,可以用javap查看

    if(java_method==0){...}//not find

    jint result=(*env)->CallIntMethod(env,obj,java_method,5,8);//obj为jobject类型通常有主函数传递来的//结果返回5+8;

     再利用这种方式实现jstring与char*之间的互相转换:

    //将const char类型转换成jstring类型
    jstring CStr2Jstring( JNIEnv* env, const char* pat )
    {
     //定义java String类 strClass
     jclass strClass = (env)->FindClass("Ljava/lang/String;");
     //获取java String类方法String(byte[],String)的构造器,用于将本地byte[]数组转换为一个新String
     jmethodID ctorID = (env)->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");
     //建立byte数组
     jbyteArray bytes = (env)->NewByteArray((jsize)strlen(pat));
     //将char* 转换为byte数组
     (env)->SetByteArrayRegion(bytes, 0, (jsize)strlen(pat), (jbyte*)pat);
     //设置String, 保存语言类型,用于byte数组转换至String时的参数
     jstring encoding = (env)->NewStringUTF("GB2312"); 
     //将byte数组转换为java String,并输出
     return (jstring)(env)->NewObject(strClass, ctorID, bytes, encoding);
    }
    
    char*   Jstring2CStr(JNIEnv*   env,   jstring   jstr)  
    {  
     char*   rtn   =   NULL;  
     jclass   clsstring   =   env->FindClass("java/lang/String");   
     jstring   strencode   =   env->NewStringUTF("GB2312");  
     jmethodID   mid   =   env->GetMethodID(clsstring,   "getBytes",   "(Ljava/lang/String;)[B");   
     jbyteArray   barr=   (jbyteArray)env->CallObjectMethod(jstr,mid,strencode);  
     jsize   alen   =   env->GetArrayLength(barr);  
     jbyte*   ba   =   env->GetByteArrayElements(barr,JNI_FALSE);  
     if(alen   >   0)  
     {  
      rtn   =   (char*)malloc(alen+1);         //new   char[alen+1];  
      memcpy(rtn,ba,alen);  
      rtn[alen]=0;  
     }  
     env->ReleaseByteArrayElements(barr,ba,0);  
     return rtn;
    } 
  • 相关阅读:
    oracle 视图views
    5分钟把任意网站变成桌面软件
    Angular http跨域
    jQuery版本升级踩坑大全
    redis 模糊删除key
    jedisCluster 报错: redis.clients.jedis.exceptions.JedisClusterException: No way to dispatch this command to Redis Cluster because keys have different slots.
    mac电脑复制键失灵
    java8 for ,forEach ,lambda forEach , strean forEach , parller stream forEach, Iterator性能对比
    linux光标操作
    redis hashmap数据结构分析
  • 原文地址:https://www.cnblogs.com/makefile/p/3773627.html
Copyright © 2011-2022 走看看