在公司项目中遇到这么一个难题

客户有一个基板,这个基板通过数据线可以连接到电脑上,装上驱动就可以调用基板提供的函数.

但是程序是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++函数相关推荐

  1. Java如何利用JNI调用C++(简略介绍及步骤)

    Java如何利用JNI调用C++(简略介绍及步骤) 文章目录 Java如何利用JNI调用C++(简略介绍及步骤) 一.原理介绍 二.详细步骤 步骤一:编写Java类 步骤二:生成.h文件 步骤三:CL ...

  2. Android之jni调用java函数总结

    1.先看之前jni的如何实现动态注册 先看我之间的例子 http://blog.csdn.net/u011068702/article/details/71375920 Android之JNI动态注册 ...

  3. Java利用JNI调用c++代码简易例子演示

    点击打开链接 (提取码:8676) 一.首先简单交代一下两个问题: 1.什么是JNI                - - -     JNI的全名为Java Native Interface(Jav ...

  4. JNI调用c++函数,该函数的参数是结构体(——对象的传递)

    第三方C++函数接口为 int api_get_logfile(Struct fileinfo tfile),参数是个结构体,且套了另一个结构体: struct fileinfo{  char *fu ...

  5. Ubuntu下,Java中利用JNI调用codeblocks c++生成的动态库的使用步骤

    1.  打开新立得包管理器,搜索JDK,选择openjdk-6-jdk安装: 2.  打开Ubuntu软件中心,搜索Eclipse,选择Eclipse集成开发环境,安装: 3.  打开Eclipse, ...

  6. windows7下,Java中利用JNI调用c++生成的动态库的使用步骤

    1.从http://www.oracle.com/technetwork/java/javase/downloads/jdk-7u2-download-1377129.html下载jdk-7u2-wi ...

  7. Linux下JNI调用简单实例操作全过程

    开发环境:Linux(Ubuntu 11.04) + JDK 7 实例说明:利用JNI调用本地代码的方法来实现一个计算Int数组总和的功能 使用JNI调用本地代码,整个开发流程主要包括以下几个步骤: ...

  8. windows下python利用f2py调用Fortran

    目录 1.运行环境 2.测试实例 3.参考文章 Fortran(Formula Translation)是世界上第一个被正式推广使用的高级语言,其目前仍然是数值计算领域最重要的编程语言之一,虽然有ju ...

  9. java中如何调用c_java中如何调用c函数

    先介绍一下jni:Java Native Interface,它能够使java和其他编程语言编写的应用程序和库进行相互操作. java中调用c函数,主要是通过本地化接口jni来实现的,在windows ...

  10. 【Android 安装包优化】使用 lib7zr.so 动态库处理压缩文件 ( jni 中 main 函数声明 | 命令行处理 | jni 调用 lib7zr.so 函数库处理压缩文件完整代码 )

    文章目录 一.JNI 中 main 函数声明 二.命令字符串切割并传入 main 函数 三.完整代码示例 1.完整 jni 代码 2.完整 java 代码 3.执行结果 四.参考资料 前置博客 : [ ...

最新文章

  1. TMG2010 之创建访问规则
  2. 《Android传感器开发与智能设备案例实战》——第1章,第1.2节Android的巨大优势...
  3. 工作152:阅读之后台管理登录样式
  4. 半素数c语言,非常简单的c题目 不懂 紧急求助
  5. HTML5文件API之FileReader
  6. abaqus移动热源DFLUX
  7. 如何为BLE 设备实现OTA DFU 空中升级功能(上)?
  8. 为什么要给代码添加注释?
  9. 他们十年发生的那些事,你好奇不?
  10. Contour 学习笔记(二):使用级联功能实现蓝绿部署和金丝雀发布
  11. 10个最好的网站数据实时分析工具
  12. python自动化定位方式
  13. 修复android.phone软件,Jihosoft Android Phone Recovery
  14. 12款国内外企业协作工具推荐
  15. WordPress站点彻底高效更换新旧域名插件Velvet Blues Update URLs
  16. 抖音视频剪辑工具有哪些?有没有教程?
  17. UnicodeDecodeError: 'gbk' codec can't decode byte 0x9c in position 63: illegal multibyte sequence
  18. 响应式多级菜单 侧边菜单栏_大菜单,小屏幕:响应式,多级导航
  19. js 模板字符串转html,JS一行代码实现一个简单的模板字符串替换
  20. 某APP逆向算法学习与分析

热门文章

  1. Axure中继器基础教程(增行、删当前、标记、全部、规则行) Mark
  2. QT学习第一步 QT下载及安装详细步骤
  3. 用PS自己制作一寸证件照照片
  4. php工程师绩效考核表_如何对程序员绩效考核?
  5. 二阶微分方程解法总结 Summary of Second Order Equations
  6. 解决PDF文件内部页面大小不一致问题
  7. 中国对数字货币的态度及政策
  8. oracle数据库卸载过程,oracle数据库卸载教程,Oracle卸载步骤有哪几步?
  9. php获取客户端IP地址的几种方法
  10. win10关闭计算机休眠,小编教您win10怎么关闭休眠 win10关闭系统休眠方法