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, , (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笔记之 初体验的更多相关文章
- Spring Boot 学习笔记1——初体验之3分钟启动你的Web应用[z]
前言 早在去年就简单的使用了一下Spring Boot,当时就被其便捷的功能所震惊.但是那是也没有深入的研究,随着其在业界被应用的越来越广泛,因此决定好好地深入学习一下,将自己的学习心得在此记录,本文 ...
- python3学习笔记.1.初体验
最近工作烦得很 就想找点儿别的事情来做,于是想到了学学python. 因为是vs2017,所以就在里面安装了. 第一个程序肯定是Hello World了. 新建一个python应用程序 代码只有一行 ...
- SpringCloud个人笔记-04-Stream初体验
sb_cloud_stream Spring Cloud Stream 是一个构建消息驱动微服务的框架 应用程序通过 inputs 或者 outputs 来与 Spring Cloud Stream ...
- SpringCloud个人笔记-03-Config初体验
sb-cloud-config 配置中心 <?xml version="1.0" encoding="UTF-8"?> <project xm ...
- SpringCloud个人笔记-02-Feign初体验
项目结构 sb_cloud_product <?xml version="1.0" encoding="UTF-8"?> <project x ...
- SpringCloud个人笔记-01-Eureka初体验
eureka是一个高可用的组件,它没有后端缓存,每一个实例注册之后需要向注册中心发送心跳,在默认情况下erureka server也是一个eureka client ,必须要指定一个 serve &l ...
- Scrapy 初体验
开发笔记 Scrapy 初体验 scrapy startproject project_name 创建工程 scrapy genspider -t basic spider_name website. ...
- VSTO学习笔记(十五)Office 2013 初体验
原文:VSTO学习笔记(十五)Office 2013 初体验 Office 2013 近期发布了首个面向消费者的预览版本,我也于第一时间进行了更新试用.从此开始VSTO系列全面转向Office 201 ...
- 数据结构(逻辑结构,物理结构,特点) C#多线程编程的同步也线程安全 C#多线程编程笔记 String 与 StringBuilder (StringBuffer) 数据结构与算法-初体验(极客专栏)
数据结构(逻辑结构,物理结构,特点) 一.数据的逻辑结构:指反映数据元素之间的逻辑关系的数据结构,其中的逻辑关系是指数据元素之间的前后件关系,而与他们在计算机中的存储位置无关.逻辑结构包括: 集合 数 ...
随机推荐
- ASP.NET MVC 教程-MVC简介
ASP.NET 是一个使用 HTML.CSS.JavaScript 和服务器脚本创建网页和网站的开发框架. ASP.NET 支持三种不同的开发模式:Web Pages(Web 页面).MVC(Mode ...
- 前端见微知著番外篇:GIT舍我其谁?
在上一篇中,我们讲到了利用纯UI的软件如何实现代码的提交.但是在MAC机器上,是没有turtoiseGit这类软件的,所以利用命令行的方式就是我们的首选了. 下面我们来描述两种主要的Git使用场景: ...
- Burndown chart
S型的燃尽图 在一次milestone开发过程中,开发者会持续编辑issue列表,每个issue都有自己的生命周期.燃尽图预期这些issues会被线性的消灭掉,所以从第一天直接到最后一天画个直线表示预 ...
- Qt学习笔记 QMessageBox
Qt的几种MessageBox 1.Infomation类型 QMessageBox::information(this,tr("hello"),tr("title&qu ...
- node 学习笔记 - Modules 模块加载系统 (2)
本文同步自我的个人博客:http://www.52cik.com/2015/12/14/learn-node-modules-module.html 上一篇讲了模块是如何被寻找到然后加载进来的,这篇则 ...
- 在nodeJs的Express框架下用TypeScript编写router路由出现import关键字错误的解决方案
问题出现场景 在项目中采用nodejs做中间层,做页面的首屏渲染,同时采用express作为主web框架,其中express的router页面路由我采用ts语言来编写.如下: //page.ts 文件 ...
- 怎样修改 Openstack Horizon(Dashboard)的显示界面 (一)
Openstack 有很多项目,比如 nova 是虚拟机管理,neutron 是虚拟网络管理, glance 是存储管理,而 horizon 是负责 Openstack 的统一界面.horizon 的 ...
- JavaScript中in操作符(for..in)、Object.keys()和Object.getOwnPropertyNames()的区别
ECMAScript将对象的属性分为两种:数据属性和访问器属性.每一种属性内部都有一些特性,这里我们只关注对象属性的[[Enumerable]]特征,它表示是否通过 for-in 循环返回属性,也可以 ...
- 基于FPGA的音频信号的FIR滤波(Matlab+Modelsim验证)
1 设计内容 本设计是基于FPGA的音频信号FIR低通滤波,根据要求,采用Matlab对WAV音频文件进行读取和添加噪声信号.FFT分析.FIR滤波处理,并分析滤波的效果.通过Matlab的分析验证滤 ...
- 将Microsoft Ajax Minifier集成到VS2013对JS、CSS进行编译时压缩
在网站发布中,一般要将js,css文件压缩减少体积,以减少在HTTP请求中的流量.将Microsoft Ajax Minifier集成到VS2013中就可以对JS.CSS进行编译时压缩. VS2013 ...