在 Android Studio 开发 JNI 的时候,总感觉被一些细枝末节所迷惑,比如 NDK,.so 文件,动态库,library ,javah 编译等等,感觉很困惑,所以这次打算撇开细枝末节,只关注最必要的东西。其实 JNI 开发和 Android 关系不大,即使在纯 Java 世界,JNI 也是一项成熟的技术,所以这次撇开 android,单纯从 Java 开发的角度,来走一遍 JNI 开发的流程。

编写 Java 代码,这里使用 IntelliJ IDEA,编写 C/C++ 代码,使用 IntelliJ Clion

第一步:首先在 IntelliJ IDEA 中创建一个 Java 项目,新建一个 JniExample.java 文件,内容如下:

其中 test 表示需要加载的由 C 文件生成的库名,window 平台下是 .dll,ubuntu 平台下是 .so 文件。下面这条语句:

public native String getStringFromC();

表示需要由 C 语言实现,由 Java 调用的方法,和普通Java 方法的区别是在 public 后面多了一个 native 关键字。

写好之后,运行 Build -> Build Project

然后会在 build/class/main/ 目录下看到生成了一个 JniExample.class 文件

这时,可以通过 shell 界面,进入该路径,然后执行如下命令(javah 需要先配置到 环境变量中)

>$javah JniExample

注意,此时不要加上 .class 后缀,否则会报错。运行结束后,可以看到在该目录下生成了文件JniExample.h

其内容如下:

到这里时,我们进入第二步,打开 IntelliJ Clion,然后新建一个 Demo 项目,并且将刚刚生成的 JniExample.h 拷贝到该项目下,并且将 {$JAVA_HOME}/include 目录下的jni.h以及{$JAVA_HOME}/include/win32 目录下的jni_md.h 也拷贝到该目录下,拷贝完后如下所示:

其中 main.cpp 是自动生成的,可以不用管他。此时会发现,JniExample.h 文件有编译错误,此时只要把第二行的 #include 修改为 #include "jni.h" 即可。然后我们新建一个 JniExample.c 文件,然后把 JniExample.h中的函数

JNIEXPORT jstring JNICALL Java_JniExample_getStringFromC(JNIEnv *, jobject);

拷贝到 JniExample.c即可,如下所示:

编写完成后,生成一个 .dll(win32平台)或者 .so(ubuntu平台),注意 ubuntu 平台下的命名:libxxx.so。下面是 ubuntu 下生成动态链接库的命令

$ gcc JniExample.c JniExample.h jni.h jni_md.h -fPIC -shared -o libtest.so

第三步:将刚才生成的 .dll 或者 .so 文件,拷贝到第一步创建的 java 项目,与 src 相同的目录下,最后在 main 函数中调用,如下所示:

注意:System.loadLibrary("test") 中的 test,对应的 .so 文件为 libtest.so,也就是说不要带上 lib 或者 .so,否则会提示错误 java.lang.UnsatisfiedLinkError: no test.so in java.library.path。

完成上面三步骤后,即可看到输出结果:

小结:在完成上面三步的过程中,有几个坑需要注意:

1、用 javah 将 JniExample.class 文件生成 JniExample.h 文件的过程中,不要带上 .class 后缀

2、将 JniExample.h拷贝到 C 项目后,需要把 #include 修改为 #include "jni.h"

3、生成的 .so,注意命名规则 libXXX.so,lib 和 .so 不能省略,在 java 中引用时,不能带上 lib和 .so。

idea java jni 调试_使用 IntelliJ IDEA 和 IntelliJ Clion 进行 JNI 开发相关推荐

  1. linux java远程调试_[转]JPDA:Java平台调试架构(常用的远程调试方法)

    原文出处:http://www.javaeye.com/topic/75128 最近使用WTP的Server功能很不爽,连tomcat服务器时java类中的任何改动都要重启服务器,一怒之下就改用JPD ...

  2. java ui调试_如何使用 IBM i System Debugger 调试 Java 程序

    当在 IBM i 上使用 Java 时,您可以使用 Qshell Interpreter 或者 CL 命令提供的 Java tools,在 Qshell 环境和 IBM i 环境上进行与 Java 开 ...

  3. eclipse java 程序调试_使用 Eclipse 调试 Java 程序的 10 个技巧

    - 友好的可读的对象 变量视图是使用对象的toString方法来现实对应的值.因为这个原因,如果提供友好的toString方法实现,对调试来说会非常有用.在javadoc中关于java.lang.Ob ...

  4. java 安卓调试_【转】Android 调试技术

    一.JAVA层单步调试 二.Native层单步调试 三.JAVA层堆栈打印 1. 在指定的函数内打印相关java调用 Log.d(TAG,Log.getStackTraceString(new Thr ...

  5. idea java 远程调试_使用idea开启远程调试

    jar程序运行在远程服务器上出现错误,又没有明确的错误日志能够查看得到,无从下手?这篇文章获取可以帮助一二. 这里我来分享一种通过idea实现远程调试的方法,几个及其简单的操作就可以使我们定位远程服务 ...

  6. pixhawk飞控调试_如何用开源飞控PIXHAWK进行二次开发?

    以下所描述的都是针对px4原生固件,此外,由于固件更新过于频繁,本文描述的是15年7月的固件,主要是举例,有改动的话,自己再研究研究吧(后面换cmake编译方式了,改动蛮大). 既然要做开发,第一步就 ...

  7. scala本地调试_如何编写自己的Java / Scala调试器

    scala本地调试 在本文中,我们将探讨Java / Scala调试器的编写和工作方式. 诸如Windows的WinDbg或Linux / Unix的gdb之类的本机调试器通过操作系统直接提供给它们的 ...

  8. java jni编译_从源码编译Android系统的Java类库和JNI动态库的方法

    利用源码编译Android系统Java类库 1.编写Java项目和Android.mk文件 ├── Android.mk └── src └── com └── lhw └── framework └ ...

  9. 如何编写自己的Java / Scala调试器

    通过这篇文章,我们将探讨Java / Scala调试器的编写和工作方式. 诸如Windows的WinDbg或Linux / Unix的gdb之类的本机调试器通过操作系统直接提供给它们的钩子来获取其强大 ...

最新文章

  1. win10多合一原版系统_win10多合一系统下载_win10多合一系统下载地址-系统城
  2. celery任务:Tasks(一)
  3. Android使用Handler造成内存泄露的分析及解决方法
  4. 基于图像分析的铁路车号识别系统
  5. jQuery 之 [ 动画 ]
  6. Solr安装并导入mysql数据
  7. 初识Mysql(part5)--我需要知道的11条Mysql语句之过滤
  8. 高手与菜鸟,思想与技术
  9. 大一C语言和线性代数,线性代数:对于编程很重要
  10. 香港城市大学计算机专业选课,香港城市大学传播与新媒体专业课程设置
  11. Design Ware IP
  12. 我的团长我的团——真正的中国军人
  13. 采用flv.js与dplayer播放器来播放http-flv格式视频
  14. 中国农业大学计算机考研参考书目,中国农业大学(专业学位)计算机技术考研参考书目...
  15. lls 在* 80端口已经绑定的情况下,批量加域名到*80端口
  16. php 数组 批量替换字符串,php数组替换字符串
  17. 虚拟机ubuntu设置和windows的共享文件夹
  18. mysql 事件报错1314_mysql 1314
  19. Linux系统 QT+Faac实时音频采集编码(QT音频采集篇)
  20. 8个最受欢迎的移动跨平台开发引擎

热门文章

  1. Matlab之数据的输入与输出
  2. Android打开相机进行人脸识别,使用虹软人脸识别引擎
  3. 在linux 创建网络会话和绑定两块网卡
  4. [开源]基于WPF实现的Gif图片分割器,提取GIf图片中的每一帧
  5. ZOJ - 3624
  6. 单张滑动tab 组件
  7. Spring aop切面插入事物回滚
  8. Web Services创建、部署、发布
  9. JavaScript保留关键字及危险变量名
  10. 在LoadRunner里何时该用 .NET Vuser协议?