`
lxy2330
  • 浏览: 468391 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

linux下jni编程指南之——HelloWorld

 
阅读更多

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学习资料的下载链接:
分享到:
评论

相关推荐

    JNI编程指南与规范.zip

    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 ...

    JNI入门之HelloWorld(一)

    ### JNI入门之HelloWorld(一)详解 #### 一、引言 JNI(Java Native Interface)是Java平台标准的一部分,它允许Java代码与其他语言写的代码进行交互。JNI接口提供了若干公共服务,并为Java虚拟机和本机应用程序或...

    JNI编程指南.pdf

    ### JNI编程指南精要 #### 引言:JNI在IT领域的独特价值 JNI(Java Native Interface),即Java本地接口,自1997年首次亮相以来,已成为Java平台与本地代码(C/C++)间桥梁的关键组成部分。对于那些希望在Java环境...

    JNI编程指南1

    本书作为一本JNI编程指南,主要分为三个部分: 1. **入门教程**:第二章通过一个简单的示例,向初次接触JNI的读者介绍其基本概念和工作原理。这部分内容适合对JNI不熟悉的初学者,帮助他们快速理解和掌握JNI的基本...

    JNI编程指南书

    ### JNI编程指南书知识点概述 #### 一、JNI的基本概念及应用场景 JNI(Java Native Interface)作为Java平台的重要组成部分,其核心价值在于能够使Java程序有效地利用现有的C/C++代码,进而实现性能优化或功能扩展...

    JNI编程指南中文版.pdf

    《JNI编程指南中文版》这一资源提供了深入理解Java Native Interface(JNI)的全面视角,尤其对于希望在Java程序中融入C/C++代码的开发者来说,是不可或缺的学习资料。以下是基于该资源的关键知识点概述: ### JNI...

    JNI编程指南.rar

    本压缩包“JNI编程指南.rar”很可能包含了一份详细的教程或者参考资料,帮助开发者深入理解和使用JNI。 JNI的核心概念包括以下几个方面: 1. **本地方法接口(Native Method Interface)**:这是Java虚拟机(JVM)...

    JNI编程指南中文版

    本指南将深入探讨JNI编程的关键概念和技术。 1. JNI简介 JNI是Java虚拟机(JVM)提供的一套接口,使得Java程序可以调用本地(非Java)代码,同时也让本地代码能够调用Java方法。这种交互方式为开发者提供了极大的...

    JNI编程指南(中文版&英文版)

    综上所述,JNI编程指南是一本全面介绍JNI的书籍,无论是初学者还是有经验的开发者,都可以从中获得关于如何在Java和本地代码之间建立桥梁的宝贵知识。通过学习和实践,开发者能够充分利用Java的平台无关性和本地代码...

    jni编程指南(中、英文版)及配套源码

    JNI编程指南是学习和理解JNI机制的关键资源,提供了详细的API文档和使用示例。该指南分为中文版和英文版,以满足不同语言背景的学习者需求。对于初学者,阅读官方文档是了解JNI最直接的方式,因为它通常是最准确、最...

    JNI编程指南.zip

    JNI在许多场景下都发挥着重要作用,比如利用C/C++库、优化性能、实现操作系统特定功能等。 JNI编程涉及到以下几个关键知识点: 1. **JNI接口定义**:JNI接口定义了Java虚拟机(JVM)与本地代码交互的一系列函数。...

    JNI编程指南-中文版

    这四种情况下你会用到本书: 1.在Java程序中复用以前写过的C/C++代码。 2.自己实现一个java虚拟机 3.学习不同语言如何进行协作,尤其是如何实现垃圾回收和多线程。 4.把一个虚拟机实现整合到用C/C++写的程序中。 ...

    jni-helloWorld

    首先,"HelloWorld"是编程中的经典例子,通常用于展示一种新语言或技术的基本用法。在这个JNI的"HelloWorld"示例中,我们可能首先会有一个Java类,它声明了一个native方法,这个方法的实现不在Java代码中,而是通过...

    JNI编程指南(文字清晰版)

    JNI(Java Native Interface)是Java平台的一个重要组成部分,它为Java程序员提供了一种与本地代码交互的方式。JNI在Java世界中扮演着桥梁...通过学习和实践,你可以掌握JNI编程,从而更好地驾驭Java和本地代码的结合。

    JNI入门教程之HelloWorld篇(详细版).doc

    ### JNI入门教程详解:HelloWorld篇 #### 一、引言与背景 Java Native Interface (JNI) 是Java语言与本地代码交互的桥梁,允许Java应用调用C或C++等本地语言编写的代码,这对于扩展Java功能、提高性能或集成已有非...

    JNI编程指南

    综上所述,JNI编程指南的重点在于如何使用JNI进行Java与其他语言代码的交互,包括数据类型的转换、方法的声明与实现、内存和异常的管理,以及同步机制和调试。正确地掌握这些知识点,可以有效地利用JNI扩展Java的...

    JNI-HelloWorld

    本示例“JNI-HelloWorld”就是关于如何使用JNI将Java与C语言结合,实现一个简单的“Hello, World!”程序。 首先,我们需要理解JNI的基本概念。JNI定义了一套接口和数据类型,使得Java代码能够声明本地方法(即非...

    JNI之Hello-JNI进阶

    1. linux下jni环境搭建 参考:http://blog.csdn.net/zhouyuanjing/article/details/7553706 2. 编写HelloJni工程,在主Activity(本例:HelloJni.java)里声明native函数: 如下: public native String ...

    JNI编程(二) —— 让C++和Java相互调用(2)

    这篇博客“JNI编程(二) —— 让C++和Java相互调用(2)”显然深入探讨了如何利用JNI实现Java与C++之间的互调用。在Java应用程序中,有时为了性能优化或者利用已有的C/C++库,我们需要借助JNI来实现这种跨语言的通信。 ...

Global site tag (gtag.js) - Google Analytics