`

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文件如下:

package com.lover.hellojni;

/**
 * 一个简单的Java JNI实例
 * 
 */
public class HelloBabyJNI {

	/*
	 * 静态构造函数,动态加载HelloBabyJNI动态库,其dll文件名为:HelloBabyJNI.dll --->由MSVC6.0软件创建
	 */
	static {
		System.load("E:/HelloBabyJNI.dll");  // 可能需要 dll链接库的绝对存放路径
	}

	/*
	 * 在Java中注册需要调用的C/C++本地方法(native method),也就是需要C/C++来实现的方法
	 */
	public native int add(int a, int b);

	// main方法,加载动态库来调用C/C++本地方法
	public static void main(String[] args) {
		HelloBabyJNI helloBabyJNI = new HelloBabyJNI();
		// 调用注册的add方法来得到返回值
		int result = helloBabyJNI.add(2, 3);
		// 输出
		System.out.println("after invoke the native method,the result is "+ result);
	}
}

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文件,内容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_lover_hellojni_HelloBabyJNI */

#ifndef _Included_com_lover_hellojni_HelloBabyJNI
#define _Included_com_lover_hellojni_HelloBabyJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_lover_hellojni_HelloBabyJNI
 * Method:    add
 * Signature: (II)I
 */
/*
 * java native method通过javah指令生成的约定接口
 *  
 */
JNIEXPORT jint JNICALL Java_com_lover_hellojni_HelloBabyJNI_add
  (JNIEnv *, jobject, jint, jint);

#ifdef __cplusplus
}
#endif
#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的方法实现,并且加入相应的形参。

// HelloBabyJNI.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved)
{
    return TRUE;
}
//以上为VC自动生成/*
 /* 这就是是java生成的头文件的native方法实现,其命名约定为 Java_包名_方法名 
 *  JNIEXPORT JNICALL JNIEnv 以及jobject皆是Jni的关键字
 * 具体实现则完全按照C++语法操作 */
JNIEXPORT jint JNICALL Java_com_lover_hellojni_HelloBabyJNI_add
  (JNIEnv * env, jobject, jint a, jint b)
{
	 int result =a+b ;
	 return result ;
}


那么,这个result则是我们本地方法需要返回给java调用者的。

最后,大功告成前,可别得意。我们需要为我们的工程添加Java JNI的头文件引用,具体添加文件在我们安装的jdk目录下。

具体操作为:在VC的菜单上选择Tools-Options…,打开选项对话框。在Directories文件夹,添加上jdk所在文件夹下的include和include/win32文件夹。

生成成dll动态链接库--->单栏上 Build--->Build HelloBabyJNI.dll ,成功运行后,会在当前工程目录下的

Debug文件下找到我们创建的HelloBabyJNI.dll动态链接库。

三、运行Java工程

通过前两个大步骤,我们成功的创建了Java工程以及其所调用的dll动态链接库,为了让系统在调用的时候能够访问到HelloBabyJNI.dll,我只是简单的将其放入C:\Window\System32文件夹下(Window7中)。 成功运行之前创建的Java工程。输出为:

总结:

在Java原生JNI调用的时候,重点掌握以下几个方面:

1、javah指令的掌握 ;

2、参数类型的映射 ;

3、生成的头文件(.h)中native method方法的理解以及实现上。

如此,则我们可以很好的掌握Java原生JNI的使用了。





分享到:
评论

相关推荐

    Qt for Android 用JNI来使C++和Java互调(目前最新版全网只有这个可用)

    "Qt for Android 用JNI来使C++和Java互调"的主题揭示了如何利用JNI(Java Native Interface)技术在Qt与Android原生系统之间建立桥梁,实现两者的交互。以下将详细介绍这一过程。 首先,Qt for Android是Qt项目的一...

    Android中JNI实现AES加密源代码

    在Android开发中,JNI(Java Native Interface)是一个关键的技术,它允许Java代码和其他语言写的代码进行交互。JNI常用于提高应用程序性能,访问特定硬件功能,或者像本例中所示,执行安全操作,如AES加密。AES...

    Android 串口 JNI 代码

    - **注册JNI函数**:在Java类中声明native方法,并使用`javah`命令生成对应的C/C++头文件,这个头文件包含了JNI函数的原型。 - **实现JNI函数**:在生成的头文件中定义这些函数,完成实际的串口操作逻辑。 - **...

    Android通过JNI调用.so动态库

    Android 通过 JNI(Java Native Interface)调用.so 动态库是 Android 开发中的一种常用技术。JNI 是一种允许 Java 代码与 native 代码之间进行交互的接口。通过 JNI,我们可以在 Android 项目中调用.so 动态库中的 ...

    使用JNI进行混合编程:在Java中调用C/C++本地库

    本教程将深入讲解如何使用JNI在Java中调用C/C++的本地库。 首先,我们需要理解JNI的基本概念。JNI提供了一套接口,让Java虚拟机(JVM)能够调用本地方法,这些方法由C或C++编写,并编译成动态链接库(如Windows下的...

    Android中JNI编程的那些事儿

    - 使用`__android_log_print`:Android SDK提供了一个原生的日志API,可以方便地在本地代码中打印日志,便于调试。 4. JNI最佳实践: - 错误处理:在本地方法中添加适当的错误检查和异常处理机制。 - 内存管理:...

    AndroidStudio jni 示例

    - 初始化JNI:在Java代码中,使用`System.loadLibrary("native-lib")`加载动态链接库(默认情况下,库名为项目名)。 - 调用JNI函数:现在可以在Java代码中像调用普通Java方法一样调用JNI函数了。 6. **运行与...

    android JNI C 调用Java

    Android JNI(Java Native Interface)是Android系统提供的一种机制,它允许Java代码调用C/C++原生代码,同时也允许C/C++代码调用Java的方法。JNI在开发高性能、低级硬件交互、使用现有C库或者优化性能的关键部分时...

    Android JNI多线程编程回调JAVA函数

    在Android开发中,JNI(Java Native Interface)是一个关键的技术,它允许Java代码和其他语言写的代码进行交互。JNI在处理性能敏感的任务,如图形渲染、硬件访问或者与C/C++库集成时,尤其有用。本话题将深入探讨如何...

    在Android中的jni里使用OpenGL ES和OpenCV渲染一幅图片

    总结起来,这个项目结合了Android的JNI、OpenGL ES和OpenCV,展示了如何在原生代码中处理图像并用OpenGL ES进行渲染,提供了一种高效且灵活的方式来显示和操作Android应用中的图像。这种技术对于需要高性能图形处理...

    android_jni.rar_android_android_jni

    Android JNI(Java Native Interface)是Android系统中用于Java与C/C++代码交互的桥梁,它允许开发者在Android应用中调用本地方法,实现性能优化、使用已有的C库或者访问硬件设备等功能。这个"android_jni.rar...

    android通过JNI访问硬件LED

    在Android系统中,Java Native Interface (JNI) 是一个关键组件,允许Java代码与其他语言(如C++或C)编写的代码进行交互。本项目聚焦于如何利用JNI来访问硬件资源,特别是控制LED设备。以下是对这个主题的详细阐述...

    Android Studio jni开发之经典入门demo

    总结起来,Android Studio中的JNI开发流程包括:配置NDK、创建JNI目录、编写C/C++代码、在Java中声明本地方法、生成JNI头文件和编译运行。这个过程可以帮助开发者理解如何在Android应用中集成原生代码,提升性能或...

    jni.rar_Android jni_JAVA串口 JNI_android_android RS232_jni

    5. **在Android应用中调用JNI**:在Java代码中,使用`System.loadLibrary()`加载生成的.so库,然后就可以通过`native`关键字调用之前声明的JNI函数了。 6. **串口管理**:在JNI中,需要处理串口的打开、关闭、设置...

    Android-JNI完整工程,实现c++调用java和java调用c++

    Android-JNI,全称为Java Native Interface,是一种技术,允许Java代码和其他语言编写的代码进行交互。这个完整工程展示了如何在Android应用中使用JNI,实现C++与Java之间的双向调用。这种技术在需要高效计算、利用...

    Android JNI使用demo

    - 使用`javah`命令(在Android Studio中,可以通过右键点击Java类并选择"Generate C++ Headers")自动生成对应的JNI头文件。这将创建一个`.h`文件,包含了Java本地方法的C/C++原型。 5. **实现本地方法**: - 在C...

    Android使用JNI调用Python so解释器

    在Android平台上,JNI(Java Native Interface)是一种技术,允许Java代码和其他语言写的代码进行交互。JNI在许多场景下被广泛使用,例如优化性能、访问特定硬件功能或利用已有的C/C++库。在这个特殊的场景中,我们...

    Android C、Java、JNI效率测试结果.doc

    Android 操作系统中,效率测试是一个非常重要的方面,特别是在使用 JNI(Java Native Interface)调用 C 语言时。这个文档描述了 Android G1 环境中,C、Java、JNI 调用(C 调 Java、Java 调 C)基本运算、方法调用...

    android studio JNI demo

    2. **创建JNI头文件**:为了在Java代码中调用C/C++函数,需要使用`javah`工具(或Android Studio的`GenerateJNI`功能)生成JNI头文件。这个头文件定义了C/C++函数的原型,这些函数将在本地代码中实现。 3. **编写...

    jni中用多线程调用java代码

    2. **生成JNI头文件**:使用`javah`工具(或者在Android Studio中自动完成)根据你的Java类生成对应的C/C++头文件。这个头文件包含了Java方法的C/C++声明。 3. **编写JNI代码**:在生成的头文件中实现你的native...

Global site tag (gtag.js) - Google Analytics