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, , (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 > )
{
rtn = (char*)malloc(alen+); //new char[alen+1];
memcpy(rtn,ba,alen);
rtn[alen]=;
}
env->ReleaseByteArrayElements(barr,ba,);
return rtn;
}

JNI笔记之 初体验的更多相关文章

  1. Spring Boot 学习笔记1——初体验之3分钟启动你的Web应用[z]

    前言 早在去年就简单的使用了一下Spring Boot,当时就被其便捷的功能所震惊.但是那是也没有深入的研究,随着其在业界被应用的越来越广泛,因此决定好好地深入学习一下,将自己的学习心得在此记录,本文 ...

  2. python3学习笔记.1.初体验

    最近工作烦得很 就想找点儿别的事情来做,于是想到了学学python. 因为是vs2017,所以就在里面安装了. 第一个程序肯定是Hello World了. 新建一个python应用程序 代码只有一行 ...

  3. SpringCloud个人笔记-04-Stream初体验

    sb_cloud_stream Spring Cloud Stream 是一个构建消息驱动微服务的框架 应用程序通过 inputs 或者 outputs 来与 Spring Cloud Stream ...

  4. SpringCloud个人笔记-03-Config初体验

    sb-cloud-config 配置中心 <?xml version="1.0" encoding="UTF-8"?> <project xm ...

  5. SpringCloud个人笔记-02-Feign初体验

    项目结构 sb_cloud_product <?xml version="1.0" encoding="UTF-8"?> <project x ...

  6. SpringCloud个人笔记-01-Eureka初体验

    eureka是一个高可用的组件,它没有后端缓存,每一个实例注册之后需要向注册中心发送心跳,在默认情况下erureka server也是一个eureka client ,必须要指定一个 serve &l ...

  7. Scrapy 初体验

    开发笔记 Scrapy 初体验 scrapy startproject project_name 创建工程 scrapy genspider -t basic spider_name website. ...

  8. VSTO学习笔记(十五)Office 2013 初体验

    原文:VSTO学习笔记(十五)Office 2013 初体验 Office 2013 近期发布了首个面向消费者的预览版本,我也于第一时间进行了更新试用.从此开始VSTO系列全面转向Office 201 ...

  9. 数据结构(逻辑结构,物理结构,特点) C#多线程编程的同步也线程安全 C#多线程编程笔记 String 与 StringBuilder (StringBuffer) 数据结构与算法-初体验(极客专栏)

    数据结构(逻辑结构,物理结构,特点) 一.数据的逻辑结构:指反映数据元素之间的逻辑关系的数据结构,其中的逻辑关系是指数据元素之间的前后件关系,而与他们在计算机中的存储位置无关.逻辑结构包括: 集合 数 ...

随机推荐

  1. 【转】$_POST 与 php://input的区别分析

    $data = file_get_contents("php://input"); php://input 是个可以访问请求的原始数据的只读流. POST 请求的情况下,最好使用 ...

  2. jQuery使用.on()无法绑定hover

    发现好像没有hover这个事件,jQuery的hover事件是一个封装,hover算不得一个事件.他只是将mouseover和mouseout合并了用mouseover和mouseout两个配合效果好 ...

  3. Java调用C/C++编写的第三方dll动态链接库(zz)

    这里主要用的方法是JNI.在网上查资料时看到很多人说用JNI非常的复杂,不仅要看很多的文档,而且要非常熟悉C/C++编程.恐怕有很多人在看到诸如此类的评论时已经决定绕道用其他方法了.本文将做详细的介绍 ...

  4. Webwork 学习之路【05】请求跳转前 xwork.xml 的读取

    个人理解 WebWork 与 Struts2 都是将xml配置文件作为 Controler 跳转的基本依据,WebWork 跳转 Action 前 xml 文件的读取依赖 xwork-1.0.jar, ...

  5. canvas api

    基本骨骼 <canvas id="canvas" width=1000 height=1000 style="border: 1px black dotted&qu ...

  6. C# 7.0 新特性2: 本地方法

    本文参考Roslyn项目中的Issue:#259. 1. C# 7.0 新特性1: 基于Tuple的“多”返回值方法 2. C# 7.0 新特性2: 本地方法 3. C# 7.0 新特性3: 模式匹配 ...

  7. Android回调

    当A页面跳往B页面做一些操作后,再从B页面回到A页面时,A页面想要回去一些B页面操作的数据时,我们一般会使用回调. 1 public class MainActivity extends Activi ...

  8. 软件工程(QLGY2015)第三次作业点评(含成绩)

    相关博文目录: 第一次作业点评 第二次作业点评 第三次作业点评 团队信息 本页点评团队1-22,其他组见:http://www.cnblogs.com/xiaozhi_5638/p/4490764.h ...

  9. 1017关于EXPLAIN的语法

    转自博客 http://blog.csdn.net/zhuxineli/article/details/14455029 explain显示了MySQL如何使用索引来处理select语句以及连接表.可 ...

  10. MySQL数据库my.cnf性能参数如何调优

    提供一个MySQL 5.6版本适合在1GB内存VPS上的my.cnf配置文件.配置文件可以到这里下载:: 下载my.cnf [client] port = 3306 socket = /tmp/mys ...