IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> JAVA中调用C语言函数简单教程 -> 正文阅读

[Java知识库]JAVA中调用C语言函数简单教程

背景知识

本地代码

在JAVA中使用其他语言的代码(如C/C++)称为本地代码。

历史原因

JAVA的早期阶段,很多人认为使用C和C++来加速JAVA应用中的关键部分是个好主意,但是实际上,虽然JAVA的代码确实没有纯C的运行快,但是JAVA平台实现要更快,也更稳定。

本地代码的应用场景

本地代码,比如C,对于跨平台需求,需要针对支持的平台提供单独的本地类库,而且使用C/C++编写的代码没有对通过使用无效指针所造成的内存腹泻提供任何包含,比如内存回收等,所以会容易破坏程序。因此,只有在必要的时候才使用本地代码,如下三种场景:

  1. 应用需要访问的系统特性和设备通过JAVA平台无法实现。
  2. 已经有了大量的测试过和调试过的用另一种语言编写的代码,比如图像算法,并且知道如何将其导出到所有的目标平台上。
  3. 通过基准测试,编写的JAVA代码比其他语言编写的等价代码要慢。

JNI

JNI是Java Native Interface的缩写,JNI是JAVA平台专门用于和本地C代码进行相互操作的API,称为JAVA本地接口。

JNI开发流程

  1. 在JAVA中先声明一个native方法。
  2. 通过javac -h或javah -jni命令导出JNI使用的C头头文件。
  3. 使用C实现本地方法。
  4. 将本地代码变异成动态库,windows下是.dll文件,linux下是.so文件。
  5. 在JAVA程序中加载步骤4中生成的类库,执行JAVA程序,最终实现JAVA本地代码。

JNI头文件规则

在JAVA中,调用本地代码,需要实现本地代码,需要编写一个相应的C函数,而C函数需要按照JAVA虚拟机的规则来实现,其规则如下:

  1. 使用完成的JAVA方法名,比如上例中,HelloNative.greeting,如果该类属于某个包,还需要在前面添加包名称,比如com.horstmann.HelloNative.greeting.
  2. 用下划线’_‘替换掉1中的所有’.’,然后添加上Java_前缀,比如:Java_HelloNative_greeting或
    Java_com_horstmann_HelloNative_greeting
  3. 如果类名中含有非ASCII字母或数字,如’_’,’$‘或大于’\u007F’的Unicode字符,用_0xxxx来替代,xxxx是该字符的Unicode值的4个十六进制数序列。
    示例
    本例中,通过简单的打印功能C函数来举例,在C中使用printf来实现某个打印函数,在JAVA中调用该功能函数。

1. 使用native创建一个本地方法。

JAVA中使用关键字native表示本地方法,在JAVA类中声明一个方法,我们先创建一个HelloNative类,代码如下:

public class HelloNative {
    public static native void greeting();
}

2. 使用javac -h生成头文件

使用 -h 标志运行javac (java 编译工具),提供头文件存放目录,实现对应头文件的生成。命令代码如下:

javac -h ./ HelloNative.java

运行上述命令后,就会在./ (当前目录)下自动生成一个名为 HelloNative.h的头文件,头文件内容如下:

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

#ifndef _Included_HelloNative
#define _Included_HelloNative
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     HelloNative
 * Method:    greeting
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_HelloNative_greeting
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

其中JNIEXPORT和JNICALL为宏定义,在头文件jni.h中定义,jni.h在JDK安装包中已经包含。他们的作用是为自动装在库的导出函数表明了依赖于编译器的说明符。

3. 编写本地方法的C代码

我们需要根据头文件中本地方法的声明原型,使用C实现,程序如下:

#include <stdio.h>
#include "HelloNative.h"

JNIEXPORT void JNICALL Java_HelloNative_greeting(JNIEnv *env, jclass cl)
{
    printf("this is hello native .c printf\n");
}

上述代码中,include了步骤2生成的头文件,另外补充了JNIEnv和jclass,默认的参数。

4. 在linux下,编写该C代码的动态库

需要说明的是,由于该C代码引用了jdk中的 jni.h头文件,所以生成动态库时,需要引用JDK的头文件位置,命令码如下:

gcc -fPIC -I/opt/ctools/jdk1.8.0_301/include/ -I/opt/ctools/jdk1.8.0_301/include/linux/ -shared -o libHelloNative.so HelloNative.c

其中/opt/ctools/jdk1.8.0_301/include/ 和 /opt/ctools/jdk1.8.0_301/include/linux为依赖jdk的头文件目录。
编译生成了 libHelloNative.so 共享库。

5. 在JAVA程序中加载步骤5中生成的类库,执行

在JAVA程序中,通过System.loadLibrary方法调用动态库,我们再编写一个HelloNativeTest测试类,代码如下:

public class HelloNativeTest {
	public static void main(String[] args)
	{
		HelloNative.greeting();
	}

	static
	{
		System.loadLibrary("HelloNative");
	}

}

使用javac 编译该测试类

javac HelloNativeTest.java

将步骤4中生成的动态库添加到库路径中,命令如下:

export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

编译生成HelloNativeTest.class 字节码, 使用java命令执行

java HelloNativeTest

执行命令结果如下:

this is hello native .c printf

至此就实现了在JAVA中调用C本地代码的完整示例。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-10-09 16:08:22  更:2021-10-09 16:10:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 21:15:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码