Android中JNI的使用之一:Java原生JNI的使用、javah指令的使用以及图解教材

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Android中JNI的使用之一:Java原生JNI的使用、javah
指令的使用以及图解教材
Java Nativie Interface(JNI,中文名称Java本地接口)标准时Java平台的一部分,它允许Java代码和其他语言写得代码进行交互。

JNI是本地编程接口,它使得Java虚拟机(VM)内部运行的Java代码能够用其他编程语言(如C、C++和汇编语言)编写的应用程序和库进行交互操作。

JNI的主要用途是为了对硬件进行访问以及追求高效率或可重用C/C++库。

Android系统中采用了JNI的方式来调用C/C++方法,然而,在Android系统里进一步加强了Java JNI的使用,使JNI的调用更具有效率。

因此,总的来说,Android 系统里可以采用两种方式来使用JNI。

第一种:Java原生JNI,使用dll等动态链接库;第二种,Android加强版JNI,通过动态加载*.so链接库来进行JNI调用。

今天,我们分析第一种JNI使用方式,也称得上是JNI入门。

由于Java与其他编程语言采用的语法不同,为了让Java与C/C++库函数能进行通信,约定的一个参数类型映射如下:
Java类型C/C++类型
void void
jboolean boolean
jint int
jlong long
jdouble double
jfloat float
jbyte jbyte
jchar char
jshort shor
上面的只是简单类型的一个映射,后面我们会完善其他参数类型的映射。

开发环境介绍(Windows下):
Eclipse:主要用来创建Java工程
MicrosoftVC++6.0:生成动态链接库供相应的Java文件加载
一、使用Eclipse创建Java工程
本例中,我们简单的创建了一个Java工程HelloBabyJNI,工程绝对路径位于E:\MyCode\AndroidCode\HelloBabyJNI路径下,主文件路径位于
\src\lover\hellojni路径下(路径对后面的javah编译很重要)
HelloBabyJNI.java文件如下:
[java] view plaincopyprint?
1.package com.lover.hellojni;
2.
3./**
4. * 一个简单的Java JNI实例
5. *
6. */
7.public class HelloBabyJNI {
8.
9./*
10. * 静态构造函数,动态加载HelloBabyJNI动态库,其dll文件名为:HelloBabyJNI.dll --->由
MSVC6.0软件创建
11. */
12.static {
13. System.load("E:/HelloBabyJNI.dll"); // 可能需要 dll链接库的绝对存放路径
14. }
15.
16./*
17. * 在Java中注册需要调用的C/C++本地方法(native method),也就是需要C/C++来实现的方法
18. */
19.public native int add(int a, int b);
20.
21.// main方法,加载动态库来调用C/C++本地方法
22.public static void main(String[] args) {
23. HelloBabyJNI helloBabyJNI = new HelloBabyJNI();
24.// 调用注册的add方法来得到返回值
25.int result = helloBabyJNI.add(2, 3);
26.// 输出
27. System.out.println("after invoke the native method,the result is "+ result);
28. }
29.}
2,编译HelloBabyJNI.java文件,生成HelloBabyJNI.class文件,位于路径
\src\lover\hellojni\HelloBabyJNI.class
3,使用javah指令编译HelloBabyJNI.class文件,生成Java与C/C++之间进行通信的约定接口,它规定了Java中nativemethod在C/C++的具体接口。

运行cmd后,进入于E:\MyCode\AndroidCode\HelloBabyJNI\src路径下,使用javah指令,指令集形式如下:
javah -classpath E:\MyCode\AndroidCode\HelloBabyJNI\src
-jni com.lover.hellojni.HelloBabyJNI,具体指令用法可以参考javah –help,本文只是重应用上。

如图所示:
成功运行后,我们可以在src文件夹下找到com_lover_hellojni_HelloBabyJNI.h文件,这个文件就是我们需要找到的约定接口,它的命名规范为包名_Java文件名。

为了可理解性,我们将其重命名为HelloBabyJNI.h文件,内容如下:
[cpp] view plaincopyprint?
1./* DO NOT EDIT THIS FILE - it is machine generated */
2.#include <jni.h>
3./* Header for class com_lover_hellojni_HelloBabyJNI */
4.
5.#ifndef _Included_com_lover_hellojni_HelloBabyJNI
6.#define _Included_com_lover_hellojni_HelloBabyJNI
7.#ifdef __cplusplus
8.extern"C" {
9.#endif
10./*
11. * Class: com_lover_hellojni_HelloBabyJNI
12. * Method: add
13. * Signature: (II)I
14. */
15./*
16. * java native method通过javah指令生成的约定接口
17. *
18. */
19.JNIEXPORT jint JNICALL Java_com_lover_hellojni_HelloBabyJNI_add
20. (JNIEnv *, jobject, jint, jint);
21.
22.#ifdef __cplusplus
23.}
24.#endif
25.#endif
PS:1, 由于-jni指令在javah中是默认选项,因此我们可以忽略掉它
2,在Dos中, .代表当前路径,也就是
E:\MyCode\AndroidCode\HelloBabyJNI\src,我们可以简单的使用 . 来指定当前路径于是,一个简约的javah指令如下所示:
此外,我们还可以在工程menu的bin文件夹下来执行javah指令,只需要将上面的bin替换src则可。

当然,最后生成的.h文件在bin文件夹下。

二、使用MS VC生成dll动态链接库:
1,创建DLL工程,如同所示:
2,下一步,选择A simple DLL project
3,接下来,生成了我们的HelloJNI工程,切换至File View视图
首先,导入我们之前生成的HelloBabyJNI.h头文件(可能我的VC环境有问题,我在这儿新建了一个HelloBabyJNI.h文件,拷贝了我们之前通过javah生成的.h的文件内容)
第二,在StdAx.h文件添加如下需要引用的头文件:
第三,在HelloBabyJNI.cpp中添加我们的native method的方法实现,并且加入相应的形参。

[cpp] view plaincopyprint?
1.<pre class="cpp" name="code">// HelloBabyJNI.cpp : Defines the entry point for the DLL
application.
2.//
3.
4.#include "stdafx.h"
5.
6.BOOL APIENTRY DllMain( HANDLE hModule,
7.DWORD ul_reason_for_call,
8.LPVOID lpReserved)
9.{
10.return TRUE;
11.}
12.//以上为VC自动生成/*
13. /* 这就是是java生成的头文件的native方法实现,其命名约定为 Java_包名_方法名
14. * JNIEXPORT JNICALL JNIEnv 以及jobject皆是Jni的关键字
15. * 具体实现则完全按照C++语法操作 */
16.JNIEXPORT jint JNICALL Java_com_lover_hellojni_HelloBabyJNI_add
17. (JNIEnv * env, jobject, jint a, jint b)
18.{
19.int result =a+b ;
20.return result ;
21.}
22.</pre><br>
23.<pre></pre>
24.<p><span style="font-size:16px"> 那么,这个result则是我们本地方法需要返回给java
调用者的。

</span></p>
25.<p><span style="font-size:16px"></span></p>
26.<p><span style="font-size:16px"> 最后,大功告成前,可别得意。

我们需要为我们的工程添加
Java JNI的头文件引用,具体添加文件在我们安装的jdk目录下。

</span></p>
27.<p>具体操作为:在VC的菜单上选择Tools-Options…,打开选项对话框。

在Directories文件夹,添加上
jdk所在文件夹下的include和include/win32文件夹。

</p>
28.<p> </p>
29.<p></p>
30.<p><span style="font-size:16px"> 生成成dll动态链接库--->单栏
上 Build--->Build HelloBabyJNI.dll ,成功运行后,会在当前工程目录下的</span></p>
31.<p><span style="font-size:16px">Debug文件下找到我们创建的HelloBabyJNI.dll动态链接库。

</span></p>
32.<p><span style="font-size:16px"> <img alt="" src="
/attachment/201108/17/0_1313593245rkRb.gif"></span></p>
33.<p><span style="font-size:16px"> </span></p>
34.<p><span style="font-size:16px"> </span></p>
35.<h2><a name="t3"></a>三、运行Java工程</h2>
36.<p><span style="font-size:16px"> 通过前两个大步骤,我们成功的创建了Java工程以及其所调
用的dll动态链接库,为了让系统在调用的时候能够访问到HelloBabyJNI.dll,我只是简单的将其放入C:\Window\System32文件夹下(Window7中)。

成功运行之前创建的Java工程。

输出为:</span></p>
37.<p><span style="font-size:16px"> </span></p>
38.<h2><a name="t4"></a>总结:</h2>
39.<p><span style="font-size:16px"> 在Java原生JNI调用的时候,重点掌握以下几个方面:
</span></p>
40.<p><span style="font-size:16px"> 1、javah指令的掌握;</span></p>
41.<p><span style="font-size:16px"> 2、参数类型的映射;</span></p>
42.<p><span style="font-size:16px"> 3、生成的头文件(.h)中native method方法的理解
以及实现上。

</span></p>
43.<p><span style="font-size:18px">如此,则我们可以很好的掌握Java原生JNI的使用了。

</span></p>
44.<p> </p>
45.<p></p>
46.<p> </p>
47.<pre></pre>
48.<pre></pre>
49.<pre></pre>。

相关文档
最新文档