- 浏览: 458553 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
mrshen:
很棒,在其他大神的博客上理清了思路看懂之后,来lz这里用例子学 ...
RED-BLACK(红黑)树的实现TreeMap源码阅读 -
a939639017:
yanf4j check不下来 ?
Java nio 2.0 AIO -
hellostory:
又是抄来的 - -
mysql分表方案 -
davidluoye:
为什么不说下支持的数据库呢?
模糊查询的优化 -
oliveevilo:
表示没看懂
Synchronized和java.util.concurrent.locks.Lock的区别
Posted on 2011-05-14 08:40 Braincol 阅读(222) 评论(0) 编辑 收藏
该示例源于jni官方编程指南——《The Java™ NativeInterface Programmer’s Guide and Specification》。
本文通过一个简单的例子来演示如何使用JNI。我们写一个JAVA程序,并用它调用一个C函数来打印“Hello World!”。
这个过程包含下面几步:
1、 创建一个类(HelloWorld.java)声明本地方法。
2、 使用javac编译源文件HollowWorld.java,产生HelloWorld.class。使用javah –jni来生成C头文件(HelloWorld.h),这个头文件里面包含了本地方法的函数原型。
3、 用C/C++代码写函数原型的实现。
4、 把C/C++函数实现编译成一个本地库,生成libHelloWorld.so。
5、 使用java命令运行HelloWorld程序,类文件HelloWorld.class和本地库(libHelloWorld.so)在运行时被加载。
这个流程如下图所示:
jni-helloworld
现在我们按上述步骤一步步的实现:
一、创建HelloWorld.java
class HelloWorld
{
private native void print();
public static void main(String[] args)
{
new HelloWorld().print();
}
static
{
System.loadLibrary("HelloWorld");
}
}
二、生成HelloWorld.class、HelloWorld.h
1. 编译HelloWorld.java生成HelloWorld.class
CD到HelloWorld.java所在的目录,在命令行中运行如下命令:
javac HelloWorld.java
在当前文件夹编译生成HelloWorld.class。
2.生成HelloWorld.h
在命令行中运行:
javah -jni HelloWorld
可能会提示如下错误:
error: cannot access HelloWorld
file HelloWorld.class not found
javadoc: error - Class HelloWorld not found.
错误的原因的是java的classpath没有包含当前路劲,解决办法有两种:
用下面的命令行代替
javah -classpath $PWD -jni HelloWorld
或者:
export CLASSPATH=$CLASSPATH:$PWD; javah -jni HelloWorld
这样就在能在当前目录下生成了HelloWorld.h,内容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorld */
#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloWorld
* Method: print
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_print
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
该文件中包含了一个函数Java_HelloWorld_print的声明。这里面包含两个参数,非常重要,后面讲实现的时候会讲到。
三、用C/C++代码写函数原型的实现
在当前目录下创建HelloWorld.cpp, 内容如下:
#include <jni.h>
#include <stdio.h>
#include "HelloWorld.h"
JNIEXPORT void JNICALL
Java_HelloWorld_print(JNIEnv *env, jobject obj)
{
printf("Hello World!\n");
}
注意必须要包含jni.h头文件,该文件中定义了JNI用到的各种类型,宏定义等。jni头文件存在于你jdk的安装路劲下,比如我的jdk安装在 /usr/lib/jvm/java-1.5.0-sun 目录下, 那么jni.h就存在于/usr/lib/jvm/java-1.5.0-sun/include目录下,这个路径待会会用到。
另外需要注意Java_HelloWorld_print的两个参数,本例比较简单,不需要用到这两个参数。但是这两个参数在JNI中非常重要。env代表java虚拟机环境,Java传过来的参数和c有很大的不同,需要调用JVM提供的接口来转换成C/C++类型的,就是通过调用env方法来完成转换的。obj代表调用的对象,相当于c++的this。当 c/C++ 函数需要改变调用对象成员变量时,可以通过操作这个对象来完成。
四、 把C/C++函数实现编译成一个本地库,生成libHelloWorld.so
在终端执行如下命令生成libHelloWorld.so:
g++ -I/usr/lib/jvm/java-1.5.0-sun/include/linux/ -I/usr/lib/jvm/java-1.5.0-sun/include/ -fPIC -shared -o libHelloWorld.so HelloWorld.cpp
在当前目录生成libHelloWorld.so。注意一定需要包含Java的include目录(请根据自己系统环境设定),因为Helloworld.c中包含了jni.h。
另外一个值得注意的是在HelloWorld.java中我们LoadLibrary方法加载的是“HelloWorld”,可我们生成的 Library却是libHelloWorld。这是Linux的链接规定的,一个库的必须要是:lib+库名+.so。链接的时候只需要提供库名就可以了
五、 使用java命令运行HelloWorld程序
在终端中输入运行HelloWorld程序:
java HelloWorld
可能会出现如下错误:
Exception in thread "main" java.lang.NoClassDefFoundError: HelloWorld
出现这个错误也是因为CLASSPATH环境变量没有包含当前目录,解决方法与上面提到的一样:
java -classpath $PWD HelloWorld
或者:
export CLASSPATH=$CLASSPATH:$PWD; java HelloWorld
紧接着可能也会出现下面的一个错误:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no HelloWorld in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1682)
at java.lang.Runtime.loadLibrary0(Runtime.java:822)
at java.lang.System.loadLibrary(System.java:993)
at HelloWorld.<clinit>(HelloWorld.java:11)
这个错误的原因是LD_LIBRARY_PATH环境变量没有包含当前目录,HelloWorld程序无法找到libHelloWorld.so这个库,解决办法如下:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD; export CLASSPATH=$CLASSPATH:$PWD; java HelloWorld
这样就能看到我们想要的结果了:
Hello World!
其实,在生成HelloWorld.h之前,我们就可以先修改好 LD_LIBRARY_PATH、CLASSPATH 这两个环境变量:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD; export CLASSPATH=$CLASSPATH:$PWD
这样生成HelloWorld.h 就只需命令: javah –jni HelloWorld; 运行HelloWorld只需命令: java HelloWorld 了。
在这里给出一个jni学习资料的下载链接:
发表评论
-
LINUX快捷键
2012-04-16 23:10 19781.关于终端的快捷键: T ... -
总结configure,pkg-config和PKG_CONFIG_PATH
2012-02-09 14:47 1439我想大家都在linux下用 ... -
SCP 使用
2012-01-17 13:42 965http://wenku.baidu.com/view/181 ... -
ctags
2011-09-25 18:15 1006Vi大家都很熟悉,某些情况下它是我们在Linux下唯一可用的文 ... -
gcc使用
2011-09-13 09:49 9891. gcc –Wall(打开编译警告) hello.c – ... -
Linux下软件安装方法总结
2011-08-31 21:03 824一、rpm包安装方式步骤:1、找到相应的软件包,比如sof ... -
Linux下C++开发初探
2011-08-31 20:56 23591.开发工具 Window ... -
Enabling Swap Space都要停留5分钟左右.
2011-08-21 22:29 1477前段时间安装Linux后,在启动时,每次到Enabling S ... -
C++中的.hpp文件与.h文件
2011-08-15 09:37 43831、是Header Plus Plus 的 ... -
python 下载
2011-07-22 16:43 1031你可以访问http://www.python.org/ 你可以 ... -
解决Fedora 10 root登陆密码无法验证问题
2011-07-22 10:31 1783<!-- 正文开始 --> 开机以roo ... -
ANT安装使用
2011-07-21 11:14 4024ant是jakarta一个非常好的 ... -
LINUX常用命令
2011-07-21 10:17 14541. 重新发布下环境变 ... -
Linux下jdk的安装 卸载
2011-07-04 21:10 820这两天闲着没事,就用VMware装了个Linux(RedHat ... -
REDHAT LINUX企业版更改IP地址,网关,DNS和MAC地址----
2011-07-01 20:56 2566Redhat 企业版更改IP地址,网关,DNS和MAC地址 ... -
ssh自动登陆RSA,DSA
2011-07-01 18:59 2407原理: 首先在客户端上 ... -
DenyHosts
2011-06-20 10:38 1562DenyHosts是Python语言写的 ... -
RSYNC使用1
2011-04-14 20:56 943rsync 有什么突出优点呢 ... -
linux 计划任务
2011-03-09 16:04 938利用apache的.htaccess访问机制可以保护ad ... -
sed 命令
2010-12-01 22:00 613Java代码 1. Sed简介 ...
相关推荐
JNI编程指南.pdf
JNI编程指南JNI编程指南JNI编程指南JNI编程指南JNI编程指南JNI编程指南
JNI编程指南.zip
JNI编程指南.rar
Andorid项目源码 JNI编程指南完整版
Java本地接口(JNI)编程指南和规范 官方中文版
JNI编程指南(中文版&英文版)
JNI入门学习第一篇:HelloWorld,主要是介绍操作步骤。
第一章简介JNI 是 JAVA 平台的一个重要特征,使用它我们可以重用以前用 C/C++写的大量代码。本书既是一个编程指南也是一个 JNI 手册。本书共包括三部
jni编程指南,中、英文版,及配套的源代码。 是学习jni的官方文档。
JNI(Java Native Inteface)编程指南,全文对Java JNI编程进行详细阐述,讲得很全面。
JNI程序员指南与规范.pdf + 06 JNI编程指南.pdf NDK开发汇总 https://blog.csdn.net/baopengjian/article/details/104615972 THIS book covers the Java™ Native Interface (JNI). It will be useful to you if ...
java jni 资料 对jni技术进行详细的描述和说明,
这四种情况下你会用到本书: 1.在Java程序中复用以前写过的C/C++代码。 2.自己实现一个java虚拟机 3.学习不同语言如何进行协作,尤其是如何实现垃圾回收和多线程。 4.把一个虚拟机实现整合到用C/C++写的程序中。 ...
从网上找的JNI编程指南,但是没有书签,为了方便自己看就添加了书签。JNI 是 JAVA 平台的一个重要特征, 使用它我们可以至用以前用 C/C++写的大量代码。本书 既是一个编程指南也是一个 JNI 手册。本书共包括三部分...
1. linux下jni环境搭建 参考:http://blog.csdn.net/zhouyuanjing/article/details/7553706 2. 编写HelloJni工程,在主Activity(本例:HelloJni.java)里声明native函数: 如下: public native String ...
JNI入门教程之HelloWorld篇(详细版).
解压后,有4个JNI资料,如下: JNI Specification.CHM JNI 简介与实现.pdf JNI编程指南.pdf JNI程序员指南与规范.pdf