使用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. Codeforces Round #536 (Div. 2) B. Lunar New Year and Food Ordering

    #include <bits/stdc++.h> #define N 300010 #define PII pair<int, int> using namespace std ...

  2. spring-mvc源码阅读笔记

    简要的做一些spring-mvc部分的源码学习笔记 Spring-mvc做的工作主要是俩大方面吧:一个是初始化一个ioc容器,一个是mvc部分的控制和视图模块的实现. 先说下ioc容器的初始化部分:i ...

  3. hdu 4937 base进制只含3456的base数

    http://acm.hdu.edu.cn/showproblem.php?pid=4937 给定一个数n,若这个数在base进制下全由3,4,5,6组成的话,则称base为n的幸运进制,给定n,求有 ...

  4. Swift3 KWWebView的页面屏幕自适应

    lazy var webView:WKWebView = { /* NSString *jScript = @"var meta = document.createElement('meta ...

  5. Android-Kotlin-空值处理&字符串比较&常量

    空值处理: [案例一:] 1.Kotlin对控制处理很严格,默认就不能写null,否则编译都不通过: 描述Car汽车对象: package cn.kotlin.kotlin_base01 /** * ...

  6. CentOS 7安装fail2ban+Firewalld防止SSH爆破与CC攻击

    准备工作 1.检查Firewalld是否启用 #如果您已经安装iptables建议先关闭 service iptables stop #查看Firewalld状态 firewall-cmd --sta ...

  7. ServiceStack DateTime数据类型转Json出现的困扰

    执行dotnet-new selfhost sstest 创建项目,然后打开解决方案 修改ssTest.ServiceModel中的Hello.cs,在HellopResponse中添加时间属性,然后 ...

  8. C# Winform 换肤

    本来计划接着上篇 C# Winform模仿百度日历,发现一时半会写不完,只写了一小半还不全,暂且搁置下.现在计划下班后每天至少写一篇博客,未能完成的等周末(不加班都情况)补充完整. 本篇博客窗体换肤, ...

  9. 关于Winform下DataGridView中实现checkbox全选反选、同步列表项的处理

    近期接手一个winform 项目,虽然之前有.net 的经验,但是对一些控件的用法还不是很熟悉. 这段时间将会记录一些在工作中遇到的坎坷以及对应的解决办法,写出来与大家分享并希望大神提出更好解决方法来 ...

  10. PANIC: Missing emulator engine program for 'x86' CPU.

    获取可用的Android模拟器 1:emulator -list-avds 获取可用的模拟器的名称(只用名称) 2:  android list -avd    获取可用的模拟器(信息详细) 获取iO ...