`

【java&&jni】jni入门篇

 
阅读更多

【序】我是为了android研究需要才开始研究JNI的。阅读本例文之前希望你按照上一篇【java】Windows7 下环境变量设置已经对环境变量进行正确设置


本文通过一个简单的例子来演示如何使用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)在运行时被加载。

现在我们按上述步骤一步步的实现:

一、创建HelloWorld.java

二、生成HelloWorld.class、HelloWorld.h

1. 编译HelloWorld.java生成HelloWorld.class

CD到HelloWorld.java所在的目录,在命令行中运行如下命令:

javac HelloWorld.java

在当前文件夹编译生成HelloWorld.class。

2.生成HelloWorld.h

在命令行中运行:

javah -jni HelloWorld    //记住是javah  而不是  java

可能会提示如下错误:

错误:无法访问HelloWorld

未找到HelloWorld的类文件

错误的原因的是java的classpath没有包含当前路劲,解决办法有两种:
用下面的命令行代替
javah -classpath $PWD -jni HelloWorld     //其中$PWD为当前路径,在win7下做好写上绝对路径
或者:

export CLASSPATH=$CLASSPATH:$PWD; javah -jni HelloWorld //Linux编译环境下的命令

这样就在能在当前目录下生成了HelloWorld.h,内容如下:

该文件中包含了一个函数Java_HelloWorld_print的声明。这里面包含两个参数,非常重要,后面讲实现的时候会讲到。

三、用C/C++代码写函数原型的实现

在当前目录下创建HelloWorld.cpp, 内容如下:

注意必须要包含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目录下,这个路径待会会用到。


函数返回类型
jstring代表的是返回类型。这里应该表示的是java的String.

JNIEXPORT JNICALL代表的是函数被JNI调用
函数名字
函数名字首先是前缀java,然后是要调用该JNI的Java类的路径,HelloWorld
接着是Java中申明的函数的名字 print
函数参数
第一个参数永远应该是JNIEnv* env,
第二个参数jobject thiz是java中的this指针。
第三个参数开始是Java的函数中的参数。


另外需要注意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程序 (执行环境为Linux,.so为Linux下动态库,不要试图在Windows下运行)

在终端中输入运行HelloWorld程序:

java HelloWorld
能会出现如下错误:

Exception in thread "main" java.lang.NoClassDefFoundError: HelloWorld

出现这个错误也是因为CLASSPATH环境变量没有包含当前目录,解决方法与上面提到的一样:

java -classpath $PWD HelloWorld

或者:

export CLASSPATH=$CLASSPATH:$PWD; java HelloWorld

紧接着可能也会出现下面的一个错误:


这个错误的原因是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入门之HelloWorld(一)

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

    教你java和C++的jni编程

    Java和C++之间的JNI(Java Native Interface)编程是一种技术,允许Java代码调用本地(非Java)代码,如C++,反之亦然。这在需要高效计算能力、利用硬件特性或者整合现有C/C++库时非常有用。以下是对标题和描述中...

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

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

    JNI入门教程之HelloWorld篇.doc

    这篇“JNI入门教程之HelloWorld篇”文档将引导我们了解如何使用JNI来开发一个简单的应用程序。 首先,我们需要明白JNI的核心概念:本地方法接口。它提供了一种方式,让Java虚拟机(JVM)能够调用非Java语言编写的...

    Java中JNI的使用(一)——native

    这篇博客文章“Java中JNI的使用(一)——native”很可能是对Java程序员如何首次接触和使用JNI的一个入门教程。 首先,我们来理解“native”关键字。在Java中,`native`是用来标记一个方法的,表示这个方法的实现是在...

    hello-jni.rar_ android jni_android hello jni_android jni hellojn

    《Android NDK与JNI开发详解:从Hello-JNI入门》 Android系统以其开源性和灵活性吸引了大量的开发者,而JNI(Java Native Interface)则是Android平台中连接Java层与原生C/C++代码的重要桥梁。JNI允许开发者在...

    Android之JNI初级篇

    总之,"Android之JNI初级篇"这篇文章应该是为开发者提供了一个全面的入门教程,帮助他们了解并掌握在Android应用中使用JNI的基本步骤和技术要点。通过学习这篇文章,开发者可以学会如何利用JNI提高应用的性能,实现...

    Android JNI开发手册

    基础篇主要覆盖了使用JNI进行Java和C/C++函数调用的基本方法,例如调用标准C库函数printf(),以及用户定义的C语言函数。中级篇和高级篇则涉及了更多的高级话题,如数组类型的传递、二维数组和String数组的处理,以及...

    jni资源,jni资源合计

    - 对于初学者而言,是一篇很好的入门指南。 #### 2. CSDN博客 - “JNI在Android开发中的应用实例” - **链接**:`http://blog.csdn.net/liu_zhen_wei/article/details/6975986` - **主要内容**:这篇博客提供了另...

    网上整理的JNI教程

    - **JNI编程系列之高级篇**:进一步探讨了在Java类中定义native方法、访问Java类的域和方法等内容。 以上内容总结了从基础到高级的JNI相关知识点,希望能帮助读者全面掌握JNI技术并应用于实际开发中。

    JNIDemo.zip

    本篇文章将通过一个简单的示例——JNIDemo,深入讲解Android JNI开发的基本流程,帮助初学者快速入门。 首先,我们需要了解JNI的基本概念。JNI是一个接口,使得Java代码可以调用本地(native)代码,本地代码通常是...

    [转]好消息,android平台从froyo 2.2开始支持jni单步调试了

    标题中的“[转]好消息,android平台从froyo 2.2开始支持jni单步调试了”揭示了一个重要的更新,即从Android Froyo (2.2)版本开始,开发者可以利用Java Native Interface (JNI)进行单步调试。这是一个重大的进步,...

    Android NDK编程首个程序hello-jni

    本篇文章将深入剖析“hello-jni”这一经典的Android NDK入门示例,帮助读者理解和掌握Android原生编程的基础知识。 “hello-jni”项目是一个简单的示例,旨在引导开发者了解如何在Android应用中使用NDK。首先,我们...

    android NDK入门篇----混合使用java和c/c++代码 源码工程

    本项目是一个关于Android NDK入门的实例,展示了如何混合使用Java和C/C++代码。我们将深入探讨这个主题,了解其关键概念、步骤以及实际应用。 首先,NDK的主要目的是为Android应用提供原生代码支持。原生代码通常比...

    【狂神说Java】JVM快速入门篇

    【狂神说Java】JVM快速入门篇 Java虚拟机(JVM)是Java平台的核心组成部分,它负责执行Java程序并提供与操作系统交互的接口。理解JVM的工作原理对于优化Java应用程序性能至关重要。本篇文章将从JVM的结构、内存模型...

    java写dll接口源码-JNI-By-Examples::sparkler:有趣的JavaJNI示例-使用CMake和C++(当然也可以是C!):double_exclamation_mark:接受PR

    年初写了这篇文章,因为需要将图像序列化任务从 Java 卸载到 C++(Java 的 GC,太糟糕了!)但是现在 Java 8 和 9 的新版本可能已经改变了。这个存储库现在很少更新,但您仍然可以将其作为入门的简单参考指南。 JNI ...

    NativeDemo.rar

    《JNI入门经典例子——NativeDemo源代码解析》 JNI(Java Native Interface)是Java平台标准的一部分,它允许Java代码和其他语言写的代码进行交互。JNI在许多场景下都是必不可少的,例如调用操作系统底层功能、加速...

    android串口开发入门之搭建ndk开发环境及第一个jni调用程序

    本篇文章将引导初学者如何搭建Android NDK开发环境以及创建并调用第一个JNI程序。 **一、NDK环境搭建** 首先确保你已经安装了Android Studio。在Android Studio中搭建NDK环境非常简单。按照以下步骤操作: 1. ...

    Java语言程序设计.基础篇(原书第8版)

    基础篇(原书第8版)》是学习Java编程的经典教材,适合初学者入门。这本书深入浅出地介绍了Java语言的基础知识,涵盖了编程的基本概念和技术。以下将围绕Java语言的核心概念、关键特性以及在本书中可能涉及的重点内容...

Global site tag (gtag.js) - Google Analytics