使用JNI调用本地代码,整个开发流程主要包括以下几个步骤:
1、创建一个Java类(IntArray.java);
2、使用javac编译该类(生成IntArray.class);
3、使用javah -jni 产生头文件(生成IntArray.h);
4、使用本地代码实现头文件中定义的方法(编写IntArray.c);
5、编译生成本地动态库(生成libIntArray.so);
6、使用Java运行程序。

创建Java类:IntArray.java

class IntArray {
private native int sumArray(int[] arr);
public static void main(String[] args) {
IntArray p = new IntArray();
int arr[] = new int[10];
for(int i = 0; i < 10; i++) {
arr[i] = i;
}
int sum = p.sumArray(arr);
System.out.println("Sum = " + sum);
}
static {
System.loadLibrary("IntArray");
}
}

注:
     1、在Java代码中声明本地方法必须有"native"标识符,native修饰的方法,在Java代码中只作为声明存在。例如: private native int sumArray(int[] arr);
     2、在调用本地方法前,必须首先装载含有该方法的本地库. 如IntArray.java中所示,置于static块中,在Java VM初始化一个类时,首先执行这部分代码,这可保证调用本地方法前,装载了本地库。

static {
  System.loadLibrary("IntArray");
 }

二、使用javac编译该类(生成IntArray.class)
javac IntArray.java
三、使用javah -jni 产生头文件(生成IntArray.h)
javah -jni IntArray

生成的 IntArray.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class IntArray */ #ifndef _Included_IntArray
#define _Included_IntArray
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: IntArray
* Method: sumArray
* Signature: ([I)I
*/
JNIEXPORT jint JNICALL Java_IntArray_sumArray
(JNIEnv *, jobject, jintArray); #ifdef __cplusplus
}
#endif
#endif

四、使用本地代码实现头文件中定义的方法(编写IntArray.c)
复制IntArray.h成IntArray.c,对于IntArray.c做以下修改:
1、添加头文件:#include "IntArray.h"
2、去掉以下几句
#ifndef _Included_IntArray
#define _Included_IntArray
#endif
3、实现头文件中定义的方法:

IntArray.c

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
#include "IntArray.h"
/* Header for class IntArray */ #ifdef __cplusplus
extern "C" {
#endif
/*
* Class: IntArray
* Method: sumArray
* Signature: ([I)I
*/
JNIEXPORT jint JNICALL Java_IntArray_sumArray
(JNIEnv *env, jobject obj, jintArray arr)
{
jint buf[] = {};
jint i = , sum = ;
(*env)->GetIntArrayRegion(env, arr, , , buf);
for(i = ; i < ; i++)
{
sum += buf[i];
}
return sum;
}
#ifdef __cplusplus
}
#endif

五、编译生成本地动态库(生成libIntArray.so)
根据本地代码(IntArray.h,IntArray.c)生成本地动态库,命令如下:

gcc -I /home/oracle/jdk1..0_05/include -I /home/oracle/jdk1..0_05/include/linux/ -fPIC -shared -o libIntArray.so IntArray.c

其中 -I后面是java的include文件夹地址,请根据您具体的java版本以及安装路径作相应改变;
-f后面的PIC表示生成的库中符号是与位置无关的(PIC就是Position Independent Code),关于PIC,可以参考这篇文章
http://www.gentoo.org/proj/en/hardened/pic-guide.xml

-shared表示共享,共享库后缀名.so可以认为是shared object的简称;
-o libIntArray.so,可以理解为编译后输出libIntArray.so库。

六、使用Java运行程序
java IntArray

可能出现以下结果:

java IntArray

Exception in thread "main" java.lang.UnsatisfiedLinkError: no IntArray in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1860)
at java.lang.Runtime.loadLibrary0(Runtime.java:845)
at java.lang.System.loadLibrary(System.java:1084)
at IntArray.<clinit>(IntArray.java:15)

分析异常提示可知,我们之前生成的共享库不在系统默认的共享库路径中,程序找不到共享库报错。
解决方法有两个:
1、临时指定共享库libIntArray.so的路径。
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH  注:该方法只在当前会话窗口有效,切换到另外一个终端窗口,则需要重新指定共享库路径。也可直接在环境变量中加入:LD_LIBRARY_PATH=.:$ORACLE_HOME/lib:/usr/lib64:/usr/lib:/usr/local/lib64:/usr/local/lib  命令行中使用:source ~/.bash_profile  使当前增加的环境变量生效

2、运行时加上参数指定共享库libIntArray.so的路径。
java -Djava.library.path=.  IntArray 注:-D:设置Java平台的系统属性。 此时JavaVM可以在当前位置找到该库。

通过以上任意方法,您都可以得到正确的运行结果:
java IntArray
Sum = 45

--------------------------------------------

文章来源于:http://www.2cto.com/os/201108/101048.html

CentOS Java C JNI的更多相关文章

  1. JAVA使用JNI调用C++动态链接库

    JAVA使用JNI调用C++动态链接库 使用JNI连接DLL动态链接库,并调用其中的函数 首先 C++中写好相关函数,文件名为test.cpp,使用g++编译为DLL文件,指令如下: g++ -sha ...

  2. 【Java的JNI快速学习教程】

    1. JNI简介 JNI是Java Native Interface的英文缩写,意为Java本地接口. 问题来源:由于Java编写底层的应用较难实现,在一些实时性要求非常高的部分Java较难胜任(实时 ...

  3. java通过jni方式获取硬盘序列号(windows,linux)

    linux系统java通过jni方式获取硬盘序列号 http://blog.csdn.net/starter110/article/details/8186788 使用jni在windows下读取硬盘 ...

  4. JAVA中JNI的简单使用

    了解JNI:JAVA因其跨平台特性而受人们喜爱,也正因此,使得它和本机各种内部联系变得很少,所以JNI(Java Native Interface)就是用来解决JAVA本地操作的一种方式.JAVA通过 ...

  5. Java通过JNI调用C/C++

    From:http://www.cnblogs.com/mandroid/archive/2011/06/15/2081093.html JNI是JAVA标准平台中的一个重要功能,它弥补了JAVA的与 ...

  6. java通过JNI接口调用C语言-初级

    JNI(java native interface):即java本地调用C的接口. 先看整体运行: 下面是过程: #vim test.java public class test{ public na ...

  7. Java通过JNI调用dll详细过程(转)

    源:Java通过JNI调用dll详细过程 最近项目有这样一个需求,在已有的CS软件中添加一个链接,将当前登录用户的用户名加密后放在url地址中,在BS的login方法里通过解密判断,如果为合法用户则无 ...

  8. centos java环境搭建

    我个人配置的是阿里云centos 7.4 64bit 不存在openjdk 看下面内容的情况下看是否存在openjdk java -version 如果返回java版本值,则存在openjdk,需要卸 ...

  9. Java之JNI的介绍与应用20170622

    /*************************************************************************************************** ...

随机推荐

  1. POJ2779 线性DP 或 杨氏三角 和 钩子公式

    POJ2779 线性DP 或 杨氏三角 和 钩子公式 本来就想回顾一下基础的线性DP谁知道今早碰到的都是这种大难题,QQQQ,不会 这个也没有去理解线性DP的解法,了解了杨氏三角和钩子公式,做出了PO ...

  2. hdu 3910 Liang Guo Sha

    题目链接:hdu 3910 Liang Guo Sha 题目大意:Alice和Bob这两个小伙伴又发明了一种新游戏, 叫两国杀, 每个人手上有两张牌,“杀” 和“闪”, 然后有三个数值A,B和C, 当 ...

  3. CSS 基础 例子 背景色 & 背景图片

    背景简写形式 : body {background:#ffffff url('img_tree.png') no-repeat right top;} 一.背景色  background-color ...

  4. 数字证书管理工具openssl和keytool的区别

    1. 用SSL进行双向身份验证意思就是在客户机连接服务器时,链接双方都要对彼此的数字证书进行验证,保证这是经过授权的才能够连接(我们链接一般的SSL时采用的是单向验证,客户机只验证服务器的证书,服务器 ...

  5. DXP快捷键记录(红色为经常用到的)

    dxp快捷键 1.设计浏览器快捷键:鼠标左击                         选择鼠标位置的文档鼠标双击                         编辑鼠标位置的文档鼠标右击   ...

  6. MySQL1安装

    ---恢复内容开始--- (1)安装MySQL ①ZIP安装 ②MSI安装(Windows Installer) Ⅰ  先从官网下载 目前选择使用Typical安装↑ 目前不勾选配置选项↑ 找到配置向 ...

  7. WPF异常捕获三种处理 UI线程, 全局异常,Task异常

    protected override void OnStartup(StartupEventArgs e){base.OnStartup(e);RegisterEvents();} private v ...

  8. Asp.Net 学习笔记(IIS不同版本和Asp.Net)

    主要目的是在网上记录一下学习笔记,如有不对,请指出 谢谢!! iis5.x: 存在问题,inet info收到动态请求后,aspnt_isapi.dll会被加载到inetinfo.exe(挂载w3sv ...

  9. AJPFX讲解外汇保证金交易的货币符号和外汇的报价方式

    AJPFX:外汇保证金交易的货币符号 认识货币名字是必须的入门基础,通过货币符号,首先要知道买卖哪个货币,下面是一些货币的符号.买卖外汇就是这些任意其中某两种货币的比值,也就是汇率.根据汇率比的升高或 ...

  10. JQuery Mobile - 导航栏选中状态代码

    class="ui-btn-active" 参考: https://wizardforcel.gitbooks.io/w3school-jqmobile/content/8.htm ...