利用JNI调用c++函数
在公司项目中遇到这么一个难题
客户有一个基板,这个基板通过数据线可以连接到电脑上,装上驱动就可以调用基板提供的函数.
但是程序是java开发的,所以就需要通过java调用基板函数,但是基板函数允许C++调用不支持java,所以就用到java调用C++
基板函数按照返回值大致分为两种
1.调用后直接返回数字,一般属于命令型函数,比如打开电源,返回0表示打开成功
2.调用后返回数组,比如需要获取采集的数据
第一种类型比较容易,用JNA、JNI都可以实现。因为只返回一个int,java比较容易接收。
第二种返回数组,因为C++有指针,当时机器函数返回的是一个内存地址,这个时候如果直接调用java是无法访问内存地址的。
因此需要转换。
当初也尝试过将返回的数组转为用逗号分割的字符串,但是长度超过300就会类似内存溢出的错误,所以最后放弃这种方式。
重点说一下第二种情况的解决方法
JAVA的代码
public class OASSInterface {//方法public native int[] SDFArray(String jsonStr,int[] iarr);public native int getButtonStatus();//加载dllstatic{File directory = new File(OASSInterface.class.getResource("/").getPath());System.load(directory+ "\\Interface.dll");}}//直接调用即可
int[] resultArr = oASSInterface.SDFArray(jsonStr, arr,)
C++代码
最后C++要生成的是一个DLL文件
JNIEXPORT jintArray JNICALL Java_css_OASSInterface_SDFArray(JNIEnv *env, jobject obj, jstring jsonstr, jintArray arr){jstring jReturn;Json::Reader reader;Json::Value json_object;const char* json_document = (char*)env->GetStringUTFChars(jsonstr,0); if (!reader.parse(json_document, json_object))return 0;//json解析获取其中的值int nTotalChannel=json_object["nTotalChannel"].asInt();//声明数组,这是最后机器返回的数值long long nNetIntensity[100] = {};//re是自定义错误编码,nStandDataAcq方式是项目的业务函数int re = nStandDataAcq(nTotalChannel*2 nNetIntensity);//最后要返回的数组jintArray intArray= env->NewIntArray(nTotalChannel+1); jboolean* pb;//就是将nNetIntensity里面的值放到pint里面//由于有些业务逻辑,我删除了部分代码,for循环就是放值,不要照抄代码jint* pint=new jint[nTotalChannel+1];for(int k=0;k<nTotalChannel;k++){pint[k] = -999;}for(int j=0;j<nTotalChannel;j++){pint[j]=nNetIntensity[j];} //std::cout << nNetIntensity[i] << std::endl;pint[nTotalChannel] = re;env->ReleaseIntArrayElements(intArray,pint,JNI_COMMIT);//JNI_COMMIT=1delete []pint; //如果使用GetIntArrayElements()得到该指针则不可以!!!否则Java直接崩溃了 return intArray;}int nStandDataAcq(int nTotalChannel,long long*nNetIntensity){//项目业务逻辑 ...
}
只是贴的部分代码,直接粘贴下来不能运行!
有几点需要说明一下
1.方法名 Java_css_OASSInterface_SDFArray 不可以随意命名,java开头,css是包名,OASSInterface是类名,SDFArray是方法名.
2.因为参数过多所以使用json作为参数传递,如果参数不多可以不使用json
3.C++的数组不能直接返回,需要转成jintArray
jni入门教程(里面包含如何创建C++程序)
http://www.runoob.com/w3cnote/jni-getting-started-tutorials.html
JNI详解
https://blog.csdn.net/hui12581/article/details/44832651
java调用C++会出现很多坑
一开始直接调用C++,出现C++返回指针地址,java无法读取问题
随后又改为返回字符串,出现字符串过长内存溢出问题
改为int数组解决问题后,换了版本高的基板后发现,第一次调用函数没有问题,第二次调用就卡主问题.
但是用C++直接运行没有问题,最后发现使用Win7系统不行,但是使用Win10就没有问题.项目结束也没有找到具体原因
开发过程中也出现好多问题,加上C++开发经验少,解决过程也是比较痛苦。出现问题请不要轻易放弃,网上有很多资料,当你解决了就会发现其实问题不是多么的复杂
利用JNI调用c++函数相关推荐
- Java如何利用JNI调用C++(简略介绍及步骤)
Java如何利用JNI调用C++(简略介绍及步骤) 文章目录 Java如何利用JNI调用C++(简略介绍及步骤) 一.原理介绍 二.详细步骤 步骤一:编写Java类 步骤二:生成.h文件 步骤三:CL ...
- Android之jni调用java函数总结
1.先看之前jni的如何实现动态注册 先看我之间的例子 http://blog.csdn.net/u011068702/article/details/71375920 Android之JNI动态注册 ...
- Java利用JNI调用c++代码简易例子演示
点击打开链接 (提取码:8676) 一.首先简单交代一下两个问题: 1.什么是JNI - - - JNI的全名为Java Native Interface(Jav ...
- JNI调用c++函数,该函数的参数是结构体(——对象的传递)
第三方C++函数接口为 int api_get_logfile(Struct fileinfo tfile),参数是个结构体,且套了另一个结构体: struct fileinfo{ char *fu ...
- Ubuntu下,Java中利用JNI调用codeblocks c++生成的动态库的使用步骤
1. 打开新立得包管理器,搜索JDK,选择openjdk-6-jdk安装: 2. 打开Ubuntu软件中心,搜索Eclipse,选择Eclipse集成开发环境,安装: 3. 打开Eclipse, ...
- windows7下,Java中利用JNI调用c++生成的动态库的使用步骤
1.从http://www.oracle.com/technetwork/java/javase/downloads/jdk-7u2-download-1377129.html下载jdk-7u2-wi ...
- Linux下JNI调用简单实例操作全过程
开发环境:Linux(Ubuntu 11.04) + JDK 7 实例说明:利用JNI调用本地代码的方法来实现一个计算Int数组总和的功能 使用JNI调用本地代码,整个开发流程主要包括以下几个步骤: ...
- windows下python利用f2py调用Fortran
目录 1.运行环境 2.测试实例 3.参考文章 Fortran(Formula Translation)是世界上第一个被正式推广使用的高级语言,其目前仍然是数值计算领域最重要的编程语言之一,虽然有ju ...
- java中如何调用c_java中如何调用c函数
先介绍一下jni:Java Native Interface,它能够使java和其他编程语言编写的应用程序和库进行相互操作. java中调用c函数,主要是通过本地化接口jni来实现的,在windows ...
- 【Android 安装包优化】使用 lib7zr.so 动态库处理压缩文件 ( jni 中 main 函数声明 | 命令行处理 | jni 调用 lib7zr.so 函数库处理压缩文件完整代码 )
文章目录 一.JNI 中 main 函数声明 二.命令字符串切割并传入 main 函数 三.完整代码示例 1.完整 jni 代码 2.完整 java 代码 3.执行结果 四.参考资料 前置博客 : [ ...
最新文章
- TMG2010 之创建访问规则
- 《Android传感器开发与智能设备案例实战》——第1章,第1.2节Android的巨大优势...
- 工作152:阅读之后台管理登录样式
- 半素数c语言,非常简单的c题目 不懂 紧急求助
- HTML5文件API之FileReader
- abaqus移动热源DFLUX
- 如何为BLE 设备实现OTA DFU 空中升级功能(上)?
- 为什么要给代码添加注释?
- 他们十年发生的那些事,你好奇不?
- Contour 学习笔记(二):使用级联功能实现蓝绿部署和金丝雀发布
- 10个最好的网站数据实时分析工具
- python自动化定位方式
- 修复android.phone软件,Jihosoft Android Phone Recovery
- 12款国内外企业协作工具推荐
- WordPress站点彻底高效更换新旧域名插件Velvet Blues Update URLs
- 抖音视频剪辑工具有哪些?有没有教程?
- UnicodeDecodeError: 'gbk' codec can't decode byte 0x9c in position 63: illegal multibyte sequence
- 响应式多级菜单 侧边菜单栏_大菜单,小屏幕:响应式,多级导航
- js 模板字符串转html,JS一行代码实现一个简单的模板字符串替换
- 某APP逆向算法学习与分析