本文地址:http://www.cnblogs.com/wavky/p/JNI.html

当你找到并鬼使神差地打开这个博文的时候,我敢肯定你已经知道什么是JNI,基本概念就不粘贴了。

百度出来的JNI调用方法,前三页几乎毫不例外的都是几年前的资料,告诉你如何设置一大堆莫名其妙的参数、如何通过命令行加工出dll并调用出来的,遗憾的是笔主打开的那堆帖子,多少都有些操作上的出入,再一个笔主对嘿嘿的命令行窗口无爱,并且,例外的帖子笔主还木有幸看到...

所以笔主狠心放下公司工作,抛弃领导的绩效奖金,花了大半天时间研究JNI的调用方法(尤其不用写命令那种),终于赶在下班的前三分钟,顺利完全通过eclipse界面调用出自定义的dll方法!那个激动就像中美建交或日本沉没或苍老师来我家做客那一瞬间那么振奋人心!!

简单准备工作:

以下具体操作方法可以直接百度,答案几乎是唯一可信的。

  1. 安装JDK,配置系统环境变量
  2. 准备好一个带CDT插件的Eclipse,笔主使用的是google的ADT Bundle,自带了CDT,对应Eclipse 3.8.0版
  3. 下载一个MinGW(免费的C/C++等语言编译器套件),笔主限于公司垃圾网络,测试时使用mingw-offline-install-20120426 v4.6.2版,安装时仅需勾选(在线安装版下载数据量约50Mb):
  • C Compiler
  • C++ Compiler
  • MinGW Developer Toolkit (Indudes MSYS Basic System)

配置MinGW的环境变量:

  1. 打开环境变量(系统变量),添加 MINGW_HOME 变量,变量值是刚才MinGW的安装地址,如 D:\Program Files\MinGW
  2. 设置path变量,编辑path变量添加 %MINGW_HOME%\bin;%MINGW_HOME%\msys\1.0\bin;
  3. 添加 LIBRARY_PATH 变量,变量值 %MINGW_HOME%\lib
  4. 添加 C_INCLUDE_PATH 变量,变量值 %JAVA_HOME%\include;%JAVA_HOME%\include\win32;%MINGW_HOME%\include
  5. 添加 CPLUS_INCLUDE_PATH 变量,内容 %JAVA_HOME%\include;%JAVA_HOME%\include\win32;%MINGW_HOME%\lib\gcc\mingw32\4.5.2\include\c++
  6. Win7点击确定后立即生效,若未生效请重启系统(参考安装JDK时配置操作)

第4、5步额外添加的%JAVA_HOME%\include;%JAVA_HOME%\include\win32;是为了让eclipse在c/c++项目中自动引入这个目录下的各种头文件,例如 jni.h,也可在具体项目的属性中以下位置进行指定:

调用JNI全过程:

创建一个普通java工程 Test,添加一个专门负责引入调用本地库的类 Native,代码如下:

 public class Native {
// 声明自定义本地库方法接口
native public static void run(); // 自动加载本地库文件,如文件名全称为 myCLib.dll
static{
System.loadLibrary("myCLib");
}
}

打开CMD....好吧,笔主承认标题党了,整个博文仅此一处需要一句简单的命令! CMD导航至项目文件夹下的 src 目录,输入 javah test.Native(需要使用包名.类名的完整限定名称),生成本地方法接口头文件 test_Native.h

刷新eclipse的 Package Explorer 应该会变成这样的目录状态,其中刚才刚才生成的 test_Native.h 文件代码如下图示(笔主抢闸创建了Test类,稍候用于调用Native类的本地方法):

创建一个新的 C 工程 MyC,期待编译成dll的时候,选择 Shared Library 下的模板:

MyC 工程内创建一个文件夹 src ,并将刚才 Test 项目中生成的 test_Native.h 头文件拷贝(或剪切)到 MyC 工程的 src 文件夹下,Test 工程下的 test_Native.h 文件在后面的项目运行过程中将不再起任何作用,可删:

*  打开 MyC 工程下的 test_Native.h ,若 #include <jni.h> 提示 Unresolved inclusion: <jni.h> 的错误警告(如下图所示),则表明目前这个C项目没有指定 jni.h 的头文件位置,参考上文 配置MinGW的环境变量 的第4、5步进行配置:

**  MyC 工程文件中接口函数代码上提示的 Syntax error 可以暂时忽略,据闻是eclipse语法检测的一个bug:

MyC 工程 src 文件夹中,新建一个C的实现类 NativeC.c ,引入接口头文件 jni.htest_Native.h ,并编写接口函数 JNICALL Java_test_Native_run 的实现(函数接口直接从 test_Native.h 中完整拷贝过来,注意加上形参):

 #include <jni.h>
#include "test_Native.h"
#include <stdio.h> JNIEXPORT void JNICALL Java_test_Native_run
(JNIEnv *env, jclass clazz){
puts("Hello JAVA, I am C.");
}

此时工程看起来应该是这样子的:

由于使用 minGW 默认生成的 dll 函数签名带有 @ 分隔符,将导致后面JNI调用时产生 java.lang.UnsatisfiedLinkError: xoxoclass.xoxomethod() 错误,因此需要执行以下步骤消除多余的 @ 符号。

配置 MyC 工程: MyC 工程上右键菜单 Properties ,左侧选择 C/C++ Build -> Settings ,右侧 Configuration 中显示的为当前正在显示的编译模板,[ Active ] 表示通过 Project->Build Project 菜单编译时使用的默认编译版本, minGW 将根据这些模板的属性设置,编译生成多套版本的 dll 或 exe ,有洁癖的同学可通过最右侧的 Manage Configurations... 按钮增删编译模板:

为了对比效果,笔主决定增加一套新模板 ReleaseNoAt ,继承默认的 Release 模板属性参数,并设置为Active,决不是因为洁癖或什么奇怪的原因:

 

OK返回刚才的编译模板属性配置界面,在 ReleaseNoAt 模板下,Tool Settins 页中的 MinGW C Linker -> Miscellaneous ,Linker flags 框中输入 -Wl,--kill-at,点击最下方的 Apply:

点击 MinGW C Linker ,显示的参数结果应该是这样的:

如果之前建立的C工程不是使用 Shared Library 模板,并且默认编译出的不是 dll 文件,可以在此选择 Build Artifact 页进行修改配置,Artifact Type 中选择 Shared Library ,Artifact extension 中选择 dll 即可,Output prefix 可指定输出 dll 文件的命名前缀:

OK确定返回代码编辑界面,在 MyC 工程上右键菜单,Build Configurations->Build All,生成所有模板的dll文件版本:

各版本 dll 如下图所示,控制台中可以见到每个 dll 生成所用的命令参数(现在显示的是 ReleaseNoAt 版本,即唯一配置了去掉@符号的模板):

为了验证默认 ReleaseReleaseNoAt 版本的区别,可用 dllexp 这个工具打开这两个 dll 文件进行查看(具体方法不告诉你):

Release版(下面这个 @8 就是一切麻烦的罪魁祸首)

ReleaseNoAt版(干净了)

回到eclipse,在 Test 工程中新建文件夹 dll (命名随意),并将上面生成的 ReleaseNoAt版 libMyC.dll 拷贝到这个dll文件夹中,重命名为 myCLib.dll(因为上文 Native类 中通过 System.loadLibrary("myCLib"); 加载了这个名字的dll文件,当然你也可以修改代码变成 System.loadLibrary("libMyC"); 来取代重命名),此后 MyC 工程将不再起任何作用,可删:

配置 Test工程 属性,指定工程的本地库目录,直接看图:

Test工程 test包中新建 Test类 (由于时间关系,笔主已经事先偷偷违建了),在main方法中引用 Native类 的本地方法run():

 public class Test {

     public static void main(String[] args) {
Native.run();
}
}

最后一步,运行起来...好吧,上面已经偷跑了,最终结果如上图所示,Hello, I am Wavky.

手把手教你通过Eclipse工程配置调用JNI完全攻略的更多相关文章

  1. 手把手教你学Dapr - 4. 服务调用

    上一篇:手把手教你学Dapr - 3. 使用Dapr运行第一个.Net程序 介绍 通过使用服务调用,您的应用程序可以使用标准的gRPC或HTTP协议与其他应用程序可靠.安全地通信. 为什么不直接用Ht ...

  2. Eclipse 工程配置与目录结构及各种文件夹(常用插件)

    .classpath..project 是 Eclipse 工程所必须的文件. OpenExplorer: 该 jar 包的下载地址:samsonw/OpenExplorer 安装配置方法:eclip ...

  3. 手把手教你使用eclipse+qemu+gdb来单步调试ARM内核【学习笔记】

    平台信息:linux4.0 平台:qemu 作者:庄泽彬 说明:笨叔叔的Linux视频的笔记 一.编译linux源码 export CROSS_COMPILE=arm-linux-gnueabi- e ...

  4. 手把手教你用Eclipse+TestNG搭建接口自动化测试框架

    转载于:http://qa.blog.163.com/blog/static/190147002201510275306185/ 把群博里关于接口自动化的文章都看了一遍,都是关于测试过程中遇到的问题及 ...

  5. Eclipse——手把手教新手安装Eclipse

    一.准备工作:安装JRE和JDK. 全名分别为:Java Runtime Environmen和Java SE Development Kit,推荐直接在某度软件中心下载即可,注意区分64位和32位. ...

  6. 手把手教你安装Eclipse最新版本的详细教程 - 大佬的鸡肋,菜鸟的盛宴(非常详细,非常实用)

    简介 首先声明此篇文章主要是针对测试菜鸟或者刚刚入门的小伙们或者童鞋们,大佬就没有必要往下看了. 写这篇文章的由来是因为后边要用这个工具,但是由于某些原因有部分小伙伴和童鞋们可能不会安装此工具,为了方 ...

  7. 手把手教你在Eclipse中使用CVS Branch功能

    Brach 的作用: 开发新版本的人员就基于 main trunk 工作,而 fix bug 的人员就基于 branch 工作. 一旦在 branch上将 Release_1_0的 bug修复了,我们 ...

  8. httpd-2.2 配置及用法完全攻略

    导读 apache是一款稳定的流行的web软件,是linux操作系统中默认的web管理软件.在RHEL/Centos系列中可以用rpm直接进行安装,服务名为httpd.apache有很多设置和调优 的 ...

  9. 手把手教你webpack、react和node.js环境配置(上篇)

    很多人刚学习react的时候,往往因为繁琐的配置而头疼,这里我将手把手教大家怎么用webpack配置react和redux的环境,这篇教程包括前端react和后台node整个网站的环境配置,对node ...

随机推荐

  1. Java学习笔记十二:Java中方法的重载

    Java中方法的重载 什么是方法的重载呢? 如果同一个类中包含了两个或两个以上方法名相同.方法参数的个数.顺序或类型不同的方法,则称为方法的重载,也可称该方法被重载了.如下所示 4 个方法名称都为 s ...

  2. JavaSE基础复习---2---2018/9/28

    目录: 1.数据类型 2.变量 3.数组 1.数据类型 谈到java的数据类型,必须知道java是强类型语言.首先,每个变量有类型,每个表达式有类型,而且每种类型是严格定义的.其次,所有的数值传递,不 ...

  3. 开发必备知识点--django项目启动时,url加载之前,执行某个.py文件

    django项目启动时,自定义执行某个py文件 在任意的app下的apps.py中的Config类下自定义ready()方法,并且调用autodiscover_modules. app01/apps. ...

  4. Java线程和多线程(十)——TimerTask

    Java中的java.util.Timer是一个工具类,可以用于调度一个线程在将来的某一个时刻执行特定的任务.Java Timer类可以将一个任务定时执行一次,或者是以后以每隔一定的时间间隔来触发一次 ...

  5. struts2官方 中文教程 系列八:异常处理

    在本教程中,我们将探讨如何启用Struts 2框架处理web应用程序生成的任何未捕获的异常.Struts 2提供了健壮的异常处理,包括能够自动记录任何未捕获的异常,并将用户重定向到错误web页面. 贴 ...

  6. 当我们访问不了虚拟机上ip上的web页面,是因为在window上要添加映射

    在主机上添加映射步骤 1.打开C盘 注意:用nopedata++打开 保存即可!

  7. Linux下启动Oracle服务和监听程序步骤

    Linux下启动Oracle服务和监听程序启动和关闭步骤整理如下: 1.安装oracle: 2.创建oracle系统用户: 3./home/oracle下面的.bash_profile添加几个环境变量 ...

  8. vue整合mui

    步骤1:下载https://github.com/dcloudio/mui   步骤2:将下载来的包中的dist文件夹 放到vue项目的assets中 步骤3:修改webpack配置 找到build下 ...

  9. PyQt的QString和python的string的区别

    转载于http://blog.chinaunix.net/uid-200142-id-4018863.html python的string和PyQt的QString的区别 python string和 ...

  10. 在 Ubuntu 16.04 LTS 上安装 Python 3.6.0

    原文连接:https://segmentfault.com/a/1190000007912666 最近 Python 3 发布了新版本 Python 3.6.0,好像又加入了不少黑魔法!- 由于暂时不 ...