毫无疑问,Java是一门非常强大的语言,但是像C、C++等本地语言(这里称为native language)已经存在了很长一段时间,基于这些语言已经实现了大量的无价的应用。谁都不想重复历史的车轮对吧!如果java能够把那些基于native language的应用集成到自己的开发应用当中,那将会是一件皆大欢喜的事情,既节省人力又节省无力,何乐而不为呢?
怎么做呢?java native methods就是这把钥匙!
java native methods就是由其它语言实现的功能方法,而并非java。它可能由是C、C++或者汇编等实现。在win32上,这些功能的实现被编译成动态链接库(在Solaris上称之为共享对象),这样操作系统就可以像变魔术一样把它加载并链接到运行在JVM上的进程里。
JNI(java native interface)是jdk的一部分,它像胶水一样将java应用和其它本地应用结合在一起,它提供了能够促使双方进行交流的所有功能。JDK也提供了一些工具在java和本地语言之间的处理方法和数据类型的映射。在本地方,接口指针是每一个本地方法实现的第一个参数,通过它JNI功能才有效访问。
现在我们知道了Java提供JNI去集成java代码和本地代码,但是否我们应该想想怎么去用它?虽然JNI增加了项目开发的复杂度,同时还有其它的缺点。我们应该在必须使用它时才使用它。如果遇到下面任意一种情况,有经验的人就会想到使用JNI:
- 当一些功能没有被java提供
- 当开发人员不能承担用JAVA重写的代价,而想去用一些已经存在的安全的库。
- 当性能成为一个大问题的时候。
- 如果一个新的开发需要将已经存在的安全合法的应用移植到其它的平台上时。
当然我们需要保持理念:JNI不是唯一的能够让JAVA和本地语言集成的解决方案,这可真是一个如果、然后如果得问题。
现在让我们来看看需要哪些基本的步骤来实现JNI方法。在java种调用本地方式是非常简单的事情。首先你需要在java类中声明一个本地方法,然后使用System的loadLibrary方法去加载包含本地方法实现的库,java类的定义如下:
class sample{
static{
System.loadLibrary("sampleImp");
}
public native int sum(int[] a, int[] b);
//rest of the class definition
}
这里sum方法由native关键字修饰是为了说明该法不是由java,而是由其它语言实现的。在java中调用native方法就跟调用普通的java方法一样。
现在我们已经完成了java所要做的工作,让我们来看看本地方(这里以C为例)为sample类的本地方sum所提供的实现。这里需要们去解析本地方法sum的原型,还要将java类型(primitives and references)转变为C类型,因为只有这样本地C语言才能够解析使用。我们可以使用java工具 javah来完成这项工作。javah的使用方法为:假设上面的sample类的java文件为sample.java。先使用javac将其编译成sample.class,接着在命令行里输入javah sample,这样就可以产生一个叫做sample.h的头文件了,它为sample.java中的native定义了ANSI C的功能原型。以sample.h为例,你可以在里面找到native方法sum的原型如下:
JNIEXPORT jint JNICALL Java_sample_sum(JNIEnv *, jobject, jintArray, jintArray);
这里JNIEXPORT和JNICALL是两个跨平台的宏。请您注意在sum方法的参数列表中增加了两个额外的参数。第一个参数叫做接口指针(interface pointer ,细心的读者会发现我在上面已经提到过),本地方法通过它来访问JNI库中的功能方法。第二个参数jobejct 是一个指向java方调用对象的引用。您也可以把jobejct想象为java中的某个关键字。每一个由javah工具转换而生成的本地方法的原型的参数列表都要添加这两个参数,它们就是java与本地语言之间的桥梁。最后您还会注意到方法的名称和参数类型改变了。sum被映射为Java_sample_sum。“int”映射为jint,int[](Java 整数类型的数组)映射为jintArray。数据类型的映射是由javah根据java名称来转换的。
最后两步是,实现sample.h,然后把它编译成库文件。
小结
本地方法的实现的基本步骤如下:
- 定义一个包含一个或多个native方法的java类
- 编译你的java类。
- 使用javah按照编译生成的class文件生成ANSI C 的头文件。
- 实现头文件中的native方法的函数原型。
- 将本地代码打包为共享库。
- 现在您的程序就可以跑起来了。
参考资料:
A Brief Introduction to Java Native Interface
分享到:
相关推荐
Java JNI(Java Native Interface)是Java平台中一个重要的特性,它允许Java代码和其他语言写的代码进行交互。JNI自Java 1.1版本引入以来,已经成为Java开发者与底层系统交互的重要工具,尤其在需要调用C/C++库或者...
JNI(Java Native Interface)是Java平台的标准组成部分,它允许Java代码和其他语言写的代码进行交互。JNI在许多场景下非常有用,比如需要利用已有的C/C++库、优化性能的关键算法或者接入操作系统特定的功能。本教程...
- **Native Method**:Java类中的方法如果需要用C/C++来实现,需要声明为`native`类型。 - **JNI函数**:在C/C++中定义的函数,用于实现Java类中的`native`方法。 - **JNI环境指针**:JNI环境中提供了一个全局指针`...
它允许将Java类中的某些方法声明为本地方法(native method),这些方法的实现则位于C/C++代码中。当Java方法被调用时,通过JNI机制,这些本地方法可以在虚拟机外部执行。 #### 三、实现步骤 **1. 定义本地方法** ...
JNI(Java Native Interface)是Java平台标准的一部分,它允许Java代码与其他语言写的代码进行交互。JNI的主要作用是让Java程序能够调用本地应用程序或者库(通常指C/C++语言编写的程序)。通过这种方式,开发者可以...
JNI(Java Native Interface)是Java平台标准的一部分,它允许Java代码和其他语言编写的代码进行交互。这里的“其他语言”通常指的是C和C++这样的本地代码。通过JNI,Java应用程序可以调用本地库中的函数,或者让...
JNI(Java Native Interface)是一种标准的接口规范,它允许Java代码与其他语言编写的代码进行交互,比如C、C++等。JNI对于开发高性能应用或者调用本地库非常有用。下面将根据提供的文件内容,详细介绍如何通过一个...
JNI,全称Java Native Interface,是Java平台标准的一部分,它允许Java代码和其他语言写的代码进行交互。JNI在很多场景下都是必要的,比如调用操作系统底层API、接入C/C++库或者提升性能敏感部分的执行效率。这篇...
4. **JNI函数**:在C/C++代码中,JNI函数遵循特定的命名规则,如`JNIEXPORT void JNICALL Java_package_class_name_method(JNIEnv *env, jobject obj, ...)` **Android NDK使用步骤** 1. **创建项目**:在Android ...
JNI(Java Native Interface)是Java平台的标准组成部分,它允许Java代码和其他语言写的代码进行交互。在Android开发中,JNI常用于提升性能、调用系统级库或者利用C/C++库来实现复杂的计算任务。本教程将围绕“AS ...
JNI(Java Native Interface)是Java平台的一部分,它允许Java代码和其他语言写的代码进行交互。在这个"android_ndk_jni_dev_HelloNDK.zip"压缩包中,我们通过一个名为"HelloNDK"的实例,深入探讨Android NDK和JNI的...
3. **本地方法栈(Native Method Stack)**:处理JNI调用,为每个Java线程维护本地方法的执行环境。 4. **堆(Heap)**:所有对象实例和数组都在堆中分配内存,是所有线程共享的一块内存区域。 5. **方法区(Method Area)...
Java开发实战从入门到精通,这是一套针对Java初学者和进阶者精心设计的视频教程,涵盖了Java语言的基础知识到高级特性的深入讲解。在本教程中,"附录3 Java内存模型"部分尤为关键,它将带领我们深入了解Java程序在...
这些方法需要遵循JNI(Java Native Interface)的规则。 **HelloJni.java** 示例代码: ```java package com.example.hellojni; import android.app.Activity; import android.os.Bundle; import android.widget....
在JNI中,我们需要使用`JNIEXPORT`和` JNICALL`宏来声明函数,并使用`JNIEXPORT void JNICALL Java_package_Name_method(JNIEnv *env, jobject obj)`这样的函数原型。`JNIEnv* env`提供了访问Java对象和调用Java方法...
12. **JNI(Java Native Interface)**:当需要与C/C++库交互时,JNI提供了调用原生代码的能力,这部分会简述其工作原理和使用步骤。 13. **Java虚拟机(JVM)**:深入解析JVM的工作原理,包括类加载机制、内存模型...
- 本地方法栈(Native Method Stack):与虚拟机栈类似,区别在于本地方法栈为使用到JNI(Java Native Interface)的本地方法服务。 - 程序计数器(Program Counter Register):当前线程所执行的字节码的行号指示...
- **可扩展性**:RMI可以通过JNI(Java Native Interface)与其他非Java系统交互,如与现有的数据库或服务器通信。 - **安全性**:RMI支持Java的安全模型,可以在调用远程方法时实施权限控制。 RMI的使用涉及到多个...
4. 本地方法接口(Native Method Interface):允许JVM调用操作系统级别的原生库。 二、基本概念 1. 字节码:Java源代码被编译成的中间语言,以.class文件形式存在,每个类一个文件。 2. 堆内存:存储所有对象实例...