JNI是Java
Native Interface的缩写。从Java 1.1开始,Java Native Interface
(JNI)标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的。当然也可以与其他语言交互,只要调用约定受支持就可以了。
但是这样做丧失了平台可移植性,但是有些时候我们这样做比较方便,比如以前我们项目组做网管软件,需要很多获取网络中的硬件信息,当然底层使用c语言进行信息扫描,一开始我们采用socket通信,实现c与java通信;但是随着数据信息的增加,socket通信任务就繁重起来,因此我们不得不自定义协议来实现socket下的复杂类型的数据通信。最后我们采用JNI非常方便的就完成了c与java的通信。主要是java调用c语言的方法。
这几天有学生问关于JNI的问题,那么就以实例 做一些简单介绍吧。
先说一下JNI开发的步骤:
- 编写带有native声明的方法的java类
- 使用javac命令编译所编写的java类
- 使用javah java类名 生成扩展名为h的头文件
- 使用C/C++实现本地方法
- 将C/C++编写的文件生成动态连接库
- 调用本地方法OK
1.java类:HelloTest.java
public class HelloTest {
public HelloTest() {
}
static {
try {
System.loadLibrary("hello");
} catch (Exception ex) {
ex.printStackTrace();
}
}
//求平方
private native int square(int
i);
public static void
main(String[] args)
{
HelloTest ht=new HelloTest();
int result=ht.square(3);
//下面输出应该是9
System.out.println("the result is :" + result);
}
}
这一步应该都没有问题,但是需要解释两个地方:
1).声明native方法:如果你想将一个方法做为一个本地方法的话,那么你就必须声明改方法为native的,并且不能实现。该方法由其他语言进行实现。一般是用c语言实现。那么就需要进行java的数据类型与c语言的数据类型映射的问题,比如:private
native int square(int
i);参数与返回值的数据类型都是int,那么c语言实现该方法时对应的数据类型是什么呢?String,float等等又该如何进行映射呢?
java类型 |
c语言类型 |
说明 |
boolean |
jboolean |
无符号 8位 |
byte |
jbyte |
无符号 8位 |
char |
jchar |
无符号,16 位 |
short |
jshort |
有符号,16 位 |
int |
jint |
有符号,32 位 |
long |
jlong |
有符号,64 位 |
float |
jfloat |
32位 |
double |
jdouble |
64位 |
void |
void |
|
还要引用数据类型:
jobject
|--jclass
|--jstring
|--jarray
|--jobjectArray
|--jbooleanArray
|--jbyteArray
|--jcharArray
|--jshortArray
|--jintArray
|--jlongArray
|--jfloatArray
|--jdoubleArray
当然,还有其他的数据类型没有列举。
2).System.loadLibrary("hello"):就是加载名称是hello的动态链接库,如果是windows下则为dll文件,如果是linux下则是so文件,系统根据jdk自动判断平台。一般该文件放在系统环境变量path中,因此我们可以吧动态链接库文件放在%JAVA_HOME%/bin目录下即可。jdk中该方法相当于:
Runtime.getRuntime().loadLibrary(String);
当然与该方法相似的是System.load(String fileName)
和Runtime.getRuntime().load(String
fileName)。程序本地方法调用前应该先加载native方法的本地实现(就是实现本地方法的动态链接库),因此该方法一般放在静态块中。
2.编译
执行javac HelloTest.java
如果没有报错则编译成为HelloTest.class文件,这一步没有什么问题。
3.生成头文件
执行javah HelloTest
会生成一个文件HelloTest.h文件,内容大致如下:
#include <jni.h>
#ifndef _Included_HelloTest
#define _Included_HelloTest
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jint JNICALL
Java_HelloTest_square
(JNIEnv *, jobject, jint);
#ifdef __cplusplus
}
#endif
#endif
关键是
JNIEXPORT jint JNICALL Java_HelloTest_square (JNIEnv *, jobject,
jint);
该方法是从java类生成供c语言实现的方法,该文件尽量不要修改。这里的数据类型就是上面的提到的映射后的数据类型,该数据类型是在
%JAVA_HOME%\include\jni.h中定义,
4.实现该方法。hello.c
#include "HelloTest.h"
JNIEXPORT jint JNICALL Java_HelloTest_square(JNIEnv *env,
jobject obj, jint r)
{
return r*r;
}
这一步也应该没有什么问题。接下来就是要生成动态连接库了。
5.生成动态链接库文件.
生成动态连接库文件,就是编译该c文件输出为动态连接库,如果是windows则生成dl文件如果是linux则生成so文件。不同的平台c语言的编译器各不相同,现在我在windows平台下使用vc的编译器进行编译(只要安装了vc++6.0就可以了)关于vc编译器CL的用法,大家可以google一下,非常麻烦的。
cl -I%java_home%\include -I%java_home%\include\win32 -LD hello.c
-Fehello.dll
生成的dll文件名在选项-Fe后面配置,这里是hello,因为在HelloTest.java文件中我们loadLibary的时候使用的名字是hello。两个地方要相同。另外需要将-I%java_home%\include
-I%java_home%\include\win32参数加上。
生成hello.dll文件之后拷贝hello.dll到%java_home%\bin目录下即可使用,最好吧HelloTest.h文件拷贝到%java_home%\include目录下。
6.调用该方法执行main函数即可运行成功:
java HelloTest 命令运行测试控制台输出结果是9
ok运行成功。
分享到:
相关推荐
JNI 开发 Eclipse 相关开发环境的搭建 JNI(Java Native Interface)是 Java 调用本地代码的接口,广泛应用于 Android 开发中。为了更好地开发 JNI 项目,需要搭建一个合适的开发环境。本文将指导读者如何在 ...
以下是对这个"android-JNI开发"主题的详细解释。 1. **JNI基础** - JNI接口提供了Java虚拟机(JVM)和本地代码之间的桥梁,使得开发者可以在Java应用程序中调用C/C++函数,反之亦然。 - JNI头文件`jni.h`包含了一...
### Android JNI开发步骤详解 #### 一、简介 JNI(Java Native Interface)是Java平台标准的一部分,它允许Java代码和其他语言写的代码进行交互。在Android开发中,JNI主要用于调用C/C++编写的本地代码,这可以...
周工的"android_jni开发文档"应该详细介绍了使用JNI进行Android开发的过程。 JNI开发流程主要包括以下几个步骤: 1. **创建本地方法接口**:在Java源代码中定义一个本地方法,使用`native`关键字标记。这个方法...
在这个"android JNI开发演示(串口收发)"项目中,我们将关注如何利用JNI实现Android设备上的串口通信。 串口通信是设备间数据传输的一种常见方式,常用于嵌入式系统和物联网应用。在Android平台上,由于操作系统对...
本教程将深入探讨Android下的JNI开发,并通过一个实际的Demo来阐述相关知识点。 1. **JNI基础** - **JNI简介**:JNI是Java平台的一部分,它为Java开发者提供了一种方式,可以直接在Java代码中调用本地(非Java)...
### JNI开发步骤详解 #### 一、JNI简介 JNI(Java Native Interface)是Java平台标准的一部分,它允许Java代码和其他语言写的代码进行交互。JNI在Java中主要用于调用C/C++函数,以此来实现高性能计算或其他Java...
首先,我们需要理解Android Studio与Eclipse在JNI开发上的差异。虽然Android Studio已经取代Eclipse成为主流的Android开发工具,但Eclipse仍然有其独特的NDK支持。在Android Studio中,我们可以直接在项目中配置C/...
JNI开发Java和C/C++互相传递List集合, 可以参考: Java从C/C++获取List集合对象:https://blog.csdn.net/niuba123456/article/details/80994166 Java传递List集合对象到C/C++ ...
以下是对“Jni开发文档”中可能包含的知识点的详细解释: 1. **JNI概述**:JNI是Java与本地代码交互的标准接口,它定义了一套API,使得Java开发者可以编写本地方法,这些方法可以直接调用非Java代码,通常是C/C++。...
Android Studio 3.4 配置 Android-JNI 开发基础教程详解 Android Studio 3.4 配置 Android-JNI 开发基础是 Android 应用程序开发中的一项重要技术,能够帮助开发者更好地编写 Android 应用程序。本文将详细介绍如何...
本资源“JNI开发.rar”显然是关于如何进行JNI开发的教程或参考资料。 JNI开发主要包括以下几个核心知识点: 1. **JNI接口定义**:JNI提供了一系列的C/C++函数接口,这些接口在Java层通过`System.loadLibrary`加载...
### JNI开发手册知识点详解 #### 一、JNI简介与背景 **Java Native Interface (JNI)**是一种标准的应用程序编程接口(API),它允许Java代码与其他语言编写的代码进行交互,特别是C和C++。通过JNI,Java应用程序...
08_10_C_06_预编译&jni开发流程08_10_C_06_预编译&jni开发流程08_10_C_06_预编译&jni开发流程08_10_C_06_预编译&jni开发流程08_10_C_06_预编译&jni开发流程08_10_C_06_预编译&jni开发流程08_10_C_06_预编译&jni开发...
Android JNI开发手册涵盖了使用Java本地接口(Java Native Interface,JNI)进行Android平台应用开发的核心知识。JNI是一种编程框架,允许Java代码和其他语言写的代码(主要是C或C++)进行交互。本手册是Android开发者...
本文将深入探讨如何在Android Studio中通过三种方式实现JNI开发,并对每种方法的配置和注意事项进行详尽的解释。 1. **使用NDK和CMake构建JNI** Android Studio集成NDK(Native Development Kit),使得原生代码...
本示例代码"NDK JNI开发例子代码2"将深入探讨如何在Android应用中使用NDK和JNI进行原生编程。 首先,我们需要理解NDK的作用。在Android应用中,主要的编程语言是Java,但有时为了优化性能,如图形处理、数学计算或...
本教程将围绕"Android JNI开发步骤"展开,详细介绍如何在Eclipse环境中进行JNI开发。 首先,我们需要创建一个Android项目。打开Eclipse,选择"File" -> "New" -> "Android Project",填写项目名称和目标SDK版本,...