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运行成功。
分享到:
相关推荐
Android JNI 开发 步骤 , 绝对详细
JNI开发 eclipse相关开发环境的搭建
android JNI开发演示(串口收发) ndk开发,串口收发,生产so库,有代码有开发说明文档,jni开发环境配合
JNI开发步骤
周工总结的jni开发流程
一个简单的android JNI 开发范例. 可以做入门学习之用
总结了Android下jni开发的一些重要知识点,并且以代码的形式提供供大家参考
JNI开发Java和C/C++互相传递List集合, 可以参考: Java从C/C++获取List集合对象:https://blog.csdn.net/niuba123456/article/details/80994166 Java传递List集合对象到C/C++ ...
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开发流程08_10_C_06_预编译&jni开发...
jni开发手册-The Java™ Native Interface Programmer’s Guide and Specification
环境:Windows XP Professional、JDK 1.6、标准C库 说明:作为Java程序员,当与c程序员进行联合开发时会使用到JNI编程技术。此时要求Java程序员必须要会使用...学习对象:需要在Windows环境下进行JNI开发的Java程序员。
这是一个jni开发的小例子,具体 的实现步骤在博客:Android关于JNI开发(1)-----eclipse工具开发。里面写的有。需要的朋友可以搜出来看一下。
利用AndroidStudio三种方式进行jni开发demo,详细介绍每种方式需要配置的文件以及注意事项
我们主要是做嵌入式开发,但是现在随着安卓工控和界面越来越来多,我们和安卓打的交道越来越 多,几年前更是安卓系统开发人员...那么我们就用到了 JNI,我们 要生成相应的库提供给上次开发人员调用。所以我们要学。
该Demo是我在实际项目中使用到的JNI常用技术总结和提炼,是另一个Android JNI开发培训课件对应的Demo
此文记录一下Android Studio 进行jni开发的基础配置以及入门教程。
安卓jni开发demo,详情查看:http://blog.csdn.net/baiyuliang2013
使用JNI开发音频转码器