idea java jni 调试_IntelliJ IDEA平台下JNI编程(一)—HelloWorld篇
JNI(Java Native Interface),出于学习JNI的目的,为了能够更方便快速地运行程序。本文的是在IDEA中进行,而不在AndroidStudio,这样能够对NDK的工作过程有个更深刻的认识,同时也能对JNI的原理有更深的理解。虽然本文是HelloWorld篇,但是其中涉及到很多内容。博主将遇到的坑都记录下来了,希望能够帮到大家。这篇文章可能是2016年的最后一篇文章了,接下来JNI相关系列文章明年推出,欢迎大家关注。
1. 搭建GCC编译环境
既然使用的了JNI,那就不可避免地需要将C/C++文件编译成dll(windows)或so(Linux)文件。因为我是在Windows平台下开发,可以有如下选择:
使用VC(或VS)编译成dll
使用GCC编译成dll
因为开发Android应用肯定是需要编译成Linux平台的so文件,因此,为了后面开发Android程序的兼容,使用GCC编译器比较好。而Windows平台下的GCC又可以有如下选择:
使用MinGW
使用Cygwin
这里我选择了MinGW,不管选择哪个,只要能让本地有GCC编译环境即可。
注意:搭建GCC编译环境时,一定要选择正确的GCC编译版本(32位和64位)。如果你本地安装的JDK是64位的,那么选择64位GCC,否则选择32位。这是为了使得编译后的库文件跟JVM的位一致,否则后面JVM无法调用dll(或so)。
1.1 安装MinGW
指定解压路径
其本质也是解压缩,把需要的MinGW库和程序解压到指定目录。如果懒的去看英文,我这里将我解压后的重新压缩了下,大家去下载并且解压即可直接使用。
解压完成后,刚才指定的解压目录中的bin加入到path环境变量中。例如上面图中解压到E:\MinGw,那么应当将E:\MinGw\bin加入到环境变量path中。注意,请确保bin目录确实在E:\MinGw中,如果不在,可能在更深一层目录中,自行确定bin的目录。
做完后,打开控制台,输入:gcc -v,如下:
2. 开始编码
2.1 编写Java文件
新建一个Java Project,创建包com.huachao.java,如下:
创建项目
在包com.huachao.java下编写HelloJNI类:
函数System.loadLibrary()是加载dll(windows)或so(Linux)库,只需名称即可,无需加入文件名后缀(.dll或.so)。native关键字将函数sayHello()声明为本地函数,由C/C++实现。具体的实现就在hello.dll(Windows平台)或hello.so(Linux平台)中
2.2 生成JNI头文件
2.2.1 手动输入javah指令
JNI生成头文件是通过JDK中提供的javah来完成,javah在 {JDKHome}/bin目录中。用法如下:
例如,将E:\Porject\out\com\huachao\java目录中的HelloJNI.class生成头文件,并放入到E:\Project\jni中:
需要注意的是,使用javah来生成头文件(.h)时,-classpath指定的是编译后的java文件(.class)的目录,而不是源文件(.java)的目录,因此在使用javah指令之前,先build一下项目(或直接运行一下)。此时会生称out目录,所有编译后的文件都会存放在这个目录中。
out目录
接下来,直接在IDEA的Terminal窗口运行javah:
执行javah指令
此时在jni目录中生成了头文件com_huachao_java_HelloJNI.h
自动生成头文件
内容如下:
接下来我们只需实现Java_com_huachao_java_HelloJNI_sayHello(JNIEnv *, jobject)即可。仔细观察就会发现这个函数名称是有规律的,即Java___,JNIEXPORT和JNICALL这两个宏定义暂时不用管。JNIEnv 和jobject后面系列文章会详细介绍,这里暂时不理会。
2.2.2 一键生成头文件
在2.2.1小节中,介绍了输入javah生成头文件方法。但是如果目录层次很深,或者是有多个需要生成头文件的class文件,这工作量太大了,当然你可以通过写个小程序来实现。但是这里有个更便捷的方法。点击File>Settings>Tools>External Tools:
External Tools
添加一个先的External Tools:
添加一个先的External Tools
在HelloJNI.java文件中点击右键>External Tools>Generate Header File,
点击生成头文件
点击生成,可以看到Terminal窗口会自动运行指令。跟2.2.1小节的指令一模一样。
3. 编写C文件并编译成dll(或so)文件
3.1 手动输入命令生成
在jni目录中新建HelloJNI.c文件,如下:
新建C文件
编辑HelloJNI.c如下:
接下来就是使用GCC对HelloJNI.c编译,在Terminal窗口输入如下:
发现报错,找不到jni.h头文件,将JDK目录中的include目录加入,即为:
又报找不到jni_md.h错误,继续将JDK目录中的include/win32加入,即:
完成编译。此时在项目中会生成HelloJNI.o文件。接下来是将HelloJNI.o转为HelloJNI.dll,即转为windows平台下的动态链接库。在Terminal中输入如下:
此时项目目录中生成了hello.dll文件:
生成dll
3.2 一键生成dll
有了前面使用External Tools一键生成头文件的经验后,我们可以将编译成dll的过程命令也加入到External Tools中。前面将c文件编译链接成dll文件分了2个命令,这里我们直接通过一个命令来完成:
这样就将c文件编译成了dll,在这里把生成的dll文件加入到了lib目录中,而不是像之前那直接放到项目底下。因此在java.library.path应该指定目录为lib。
有了上面的命令后,可以很轻松的加入到External Tools中了。按照前面的方法,点击File>Settings>Tools>External Tools>+,输入内容如下:
name:Generate DLL
Program:
Parameters:-Wl,--add-stdcall-alias -I"$JDKPath$\include" -I"$JDKPath$\include\win32" -shared -o ./lib/$FileNameWithoutExtension$.dll ./jni/$FileNameWithoutExtension$.c
Working Directory:$ProjectFileDir$
添加External Tools
在HelloJNI.c中点击右键,选择External Tools>Generate DLL。此时,在lib目录中会得到dll文件。
4. 运行
运行HelloJNI.java类后,如下:
运行结果
5 可能出现的错误
5.1 java.library.path找不到dll的错误
此时,点击直接运行HelloJNI.java类时,依然还会有错误:
即找不到我们生成的dll文件。因为在Windows中JVM的java.library.path属性即为环境变量Path指定的目录,而我们生成的dll并未放入到Path指定的任何一个目录中,因此我们需要告诉JVM,dll文件在哪个目录中。点击Run > Edit Configurations...,如下:
修改Edit Configurations
在VM options中加入java.library.path,指定dll(或so)文件所在的目录,比如本文中dll放在项目目录中的lib中,如下:
如下图所示:
修改VM options
5.2 无法识别__int64类型错误
错误如下:
出现这个错误的人一般是使用Cygwin GCC的人,这是因为Cygwin GCC不认识__int64类型,找到/include/win32/jni_md.h,找到typedef __int64 jlong;并修改为:
或者是编译时将__int64加入,如下:
5.3 64-bit mode not compiled
错误如下:
出现这个错误是因为,JDK版本是64位,而GCC编译器编译出的dll(或so)是32位,只需换个64位版本的GCC即可。
name:Generate DLL
Program:F:\MinGW\mingw64\bin\gcc.exe
Parameters:-Wl,--add-stdcall-alias -I"$JDKPath$\include" -I"$JDKPath$\include\win32" -shared -o $ModuleFileDir$/lib/$FileNameWithoutExtension$.dll $ModuleFileDir$/jni/$FileNameWithoutExtension$.cpp -lstdc++Working Directory:$ProjectFileDir$
name:Generate Header File
Program:$JDKPath$/bin/javah
Parameters:-jni -classpath $OutputPath$ -d $ModuleFileDir$/jni $FileClass$
Working Directory:$ProjectFileDir$
参考资料
idea java jni 调试_IntelliJ IDEA平台下JNI编程(一)—HelloWorld篇相关推荐
- Linux平台下C++编程
关于Linux下开发应该具备哪些基础知识,应该如何进阶.除了C++的基本语法知识外,应该学习哪些内容,更有助于工作和成长.同事给出了他自己的学习思路.具体如下: 1.STL STL作为已经被发明过的轮 ...
- 博途PLC和CODESYS平台下FB编程应用(如何实例化多个FB)
这里有面向对象编程的思想,大家可以好好体会.鉴于实例化概念的重要性,以及在处理一些大量重复控制算法或者对象时的优势(比如系统里有大量的气缸.轴类.泵等),这时候实例化多个FB的优势就很明显了.本文会详 ...
- Android L系统mtk平台下AAL自动背光调整服务亮度曲线调试需要涉及的地方
Android L系统mtk平台下AAL自动背光调整服务亮度曲线调试需要涉及的地方 如果你想修改MTK的AAL自动背光调整相关的内容,那么根据情况,可能需要涉及如下文件: 这是Android L版本的 ...
- java git服务器_Windows平台下Git服务器搭建
第一步:下载Java,下载地址:http://www.java.com/zh_CN/ 第二步:安装Java.安装步骤不再详述. 第三步:配置Java环境变量. 右键"计算机" =& ...
- java saas osgi_基于云计算Saas平台下的C2C大型网上商城(集UC聊天客户端+Extjs+Oracle+OSGI模型)...
基于云计算Saas平台下的C2C大型网上商城(集UC聊天客户端+Extjs+Oracle+OSGI模型) 分享网盘地址--https://pan.baidu.com/s/1slbTv33密码: u7w ...
- Linux平台下Java调用C函数
JNI是Java native interface的简写,可以译作Java原生接口.Java可以通过JNI调用C/C++的库,这对于那些对性能要求比较高的Java程序无疑是一个 福音. 使用JNI也是 ...
- 安卓平台下的GPS架构介绍及驱动移植记录
一.前言 我的工作是关于汽车车机BSP部分. 汽车车机,其实基本和人们日常所用的手机一样,也是安卓平台的.所谓安卓,就是一层安卓服务包裹着Linux内核所形成的操作系统. BSP组,主要工作内容就是负 ...
- Android平台下Dalvik层hook框架ddi的研究
通过adbi,可以对native层的所有代码进行hook.但对于Android系统来说,这还远远不够,因为很多应用都还是在Dalvik虚拟机中运行的. 那么,有没有什么办法可以对Dalvik虚拟机中跑 ...
- android平台下OpenGL ES 3.0从零开始
OpenGL ES 3.0学习实践 android平台下OpenGL ES 3.0从零开始 android平台下OpenGL ES 3.0绘制纯色背景 android平台下OpenGL ES 3.0绘 ...
最新文章
- 源码编译安装httpd及其常见错误
- ADO.NET Entity Framework 学习(1) [ZT]
- 日期控件的点击事件,在js中添加callback属性,不在html中直接添加
- iOS之性能优化·优化App的启动速度
- 【bzoj2006】【NOI2015】超级钢琴
- iframe URI钓鱼
- windows创建进程的过程
- 运行100万秒无错误!
- ajax的理解与工作流程
- 【Unity】入门级Unity安装教程
- 龙之谷服务器列表不显示,龙之谷服务器列表,龙之谷服务器列表弹不出来
- 面试小纸条(MySQL第一弹)
- 原生JS JavaScript实现懒加载效果
- 2020/5/4/ 每日一咕
- 组建自己的局域网(可以将PC机实现为服务器)
- cad标注样式快捷键_CAD新手福利:不懂标注样式修改的请进来一看
- pycharm无法关闭的高亮显示原因
- Thunderbird配置Exchange邮箱
- 杰奇百度推送php文件,杰奇版百度自动化推送插件
- Arduino开发(一)_软件开发IDE工具的安装
热门文章
- 激光雷达基础-光探测和测距-遥感
- Linux内存技术分析(上)
- ARM NEON指令集优化理论与实践
- 山西农业大学c语言答案,第一章C语言及程序设计概述-东北农业大学教务处.doc...
- HarmonyOS开发工具DevEcoStudio 的下载以及运行(包含下载开发工具,sdk,模拟机,以及运行第一个应用你好,世界)
- Android 动态广播与静态广播
- Unable to inject views for BcFragment{8d4c0 #1 id=0x7f0d00a1}
- 目标反射回波检测算法及其FPGA实现 之一:算法概述
- 中国互联网+光伏发电行业商业模式创新与投资机会深度研究报告
- 怎么给html页面添加网格线,html – 如何使用css制作网格(如图纸网格)?