java中native的用法

2023-11-05

Java开发中会碰到声明为 native的方法,如:public native int hashCode(); 这是一个native方法。为什么存在native方法呢?Java不是完美的,Java的不足除了体现在运行速度上要比传统的C++慢许多之外,Java无法直接访问到操作系统底层(如系统硬件等),为此Java使用native方法来扩展Java程序的功能。
  可以将native方法比作Java程序同C程序的接口,其实现步骤:
  1、在Java中声明native()方法,然后编译。
  2、用javah产生一个.h文件。
  3、写一个.cpp文件实现native导出方法,其中需要包含第二步产生的.h文件(注意其中又包含了JDK带的jni.h文件)。
  4、将第三步的.cpp文件编译成动态链接库文件。
  5、在Java中用System.loadLibrary()方法加载第四步产生的动态链接库文件,这个native()方法就可以在Java中被访问了。

  JAVA的native方法适用的情况:
  1、为了使用底层的主机平台的某个特性,而这个特性不能通过JAVA API访问。
  2、为了访问一个老的系统或者使用一个已有的库,而这个系统或这个库不是用JAVA编写的。
  3、为了加快程序的性能,而将一段时间敏感的代码作为本地方法实现。

这就是Java JNI的应用,小例子如下:

1) 编写
java程序:这里以HelloWorld为例。
代码1:
1
2
3
4
5
6
7
8
9
public  class  HelloWorld {
     public  native  void  displayHelloWorld(); //所有native关键词修饰的都是对本地的声明
     static  {
         System.loadLibrary( "hello" ); //载入本地库
     }
     public  static  void  main(String[] args) {
         new  HelloWorld().displayHelloWorld();
     }
}
        声明 native方法:如果你想将一个方法做为一个本地 方法的话,那么你就必须声明该方法为native的,并且不能实现。其中方法的参数和返回值在后面讲述。 Load动态库:System.loadLibrary("hello");加载 动态库(我们可以这样理解:我们的方法 displayHelloWorld()没有实现,但是我们在下面就直接使用了,所以必须在使用之前对它进行初始化)这里一般是以 static块进行加载的。同时需要注意的是System. loadLibrary();的参数“hello”是动态库的名字。
 
2) 编译
没有什么好说的了 javac  HelloWorld.java
 
3) 生成扩展名为h的头文件javah HelloWorld
jni HelloWorld 头文件的内容:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*DO NOT EDI TTHIS FILE - it is mach inegenerated*/
#include<jni.h>
/*Header for class HelloWorld*/
 
#ifndef_Included_HelloWorld
#define_Included_HelloWorld
#ifdef__cplusplus
extern "C" {
#endif
/*
*Class:HelloWorld
*Method:displayHelloWorld
*Signature:()V
*/
JNIEXPORTvoidJNICALL
Java_HelloWorld_displayHelloWorld(JNIEnv*,jobject);
 
#ifdef__cplusplus
}
#endif
#endif
        (这里我们可以这样理解:这个h文件相当于我们在java里面的接口,这里声明了一个Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject);方法,然后在我们的本地方法里面实现这个方法,也就是说我们在编写 C/C++程序的时候所使用的方法名必须和这里的一致)。
 
4) 编写本地方法
        实现和由javah命令生成的头文件里面声明的方法名相同的方法。
代码2:
1
2
3
4
5
6
7
8
9
10
11
#include"jni.h"
#include"HelloWorld.h"
 
//#includeotherheaders
 
JNIEXPORT  void  JNICALL
Java_HelloWorld_displayHelloWorld(JNIEnv*env,jobject obj)
{
printf ( "Helloworld!\n" );
return ;
}
 
        注意代码2中的第1行,需要将jni.h(该文件可以在%JAVA_HOME%/include文件夹下面找到)文件引入,因为在程序中的JNIEnv、 jobject等类型都是在该头文件中定义的;另外在第2行需要将HelloWorld.h头文件引入(我是这么理解的:相当于我们在编写java程序的时候,实现一个 接口的话需要声明才可以,这里就是将HelloWorld.h头文件里面声明的方法加以实现。当然不一定是这样)。然后保存为 HelloWorldImpl.c就ok了。
 
5) 生成动态库
        这里以在Windows中为例,需要生成dll文件。在保存HelloWorldImpl.c文件夹下面,使用 VC编译器cl成。 cl -I%java_home%\include -I%java_home%\include\win32 -LD HelloWorldImp.c -Fehello.dll 注意:生成的dll文件名在选项-Fe后面配置,这里是hello,因为在HelloWorld.java文件中我们loadLibary的时候使用的名字是hello。当然这里修改之后那里也需要修改。另外需要将-I%java_home%\include -I%java_home%\include\win32参数加上,因为在第四步里面编写本地方法的时候引入了jni.h文件。
如果配置了MinGW,也可以这样来编译:gcc -Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at -Id:/java/include –Id:/java/include/win32 -shared -o (输出的dll文件名,如sum.dll) (输入的c/c++源文件,如abc.c)。
6) 运行程序
        javaHelloWorld就ok.
        如果用eclipse,需将dll或so文件放在项目下,而不是src及其子目录下。
        如果用命令行编译,把dll文件放在该包的同目录下。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java中native的用法 的相关文章

  • 为什么 i++ 不是原子的?

    Why is i Java 中不是原子的 为了更深入地了解 Java 我尝试计算线程中循环的执行频率 所以我用了一个 private static int total 0 在主课中 我有两个线程 主题 1 打印System out prin
  • 如何在 Play java 中创建数据库线程池并使用该池进行数据库查询

    我目前正在使用 play java 并使用默认线程池进行数据库查询 但了解使用数据库线程池进行数据库查询可以使我的系统更加高效 目前我的代码是 import play libs Akka import scala concurrent Ex
  • 给定两个 SSH2 密钥,我如何检查它们是否属于 Java 中的同一密钥对?

    我正在尝试找到一种方法来验证两个 SSH2 密钥 一个私有密钥和一个公共密钥 是否属于同一密钥对 我用过JSch http www jcraft com jsch 用于加载和解析私钥 更新 可以显示如何从私钥 SSH2 RSA 重新生成公钥
  • 使用 Android 发送 HTTP Post 请求

    我一直在尝试从 SO 和其他网站上的大量示例中学习 但我无法弄清楚为什么我编写的示例不起作用 我正在构建一个小型概念验证应用程序 它可以识别语音并将其 文本 作为 POST 请求发送到 node js 服务器 我已确认语音识别有效 并且服务
  • Final字段的线程安全

    假设我有一个 JavaBeanUser这是从另一个线程更新的 如下所示 public class A private final User user public A User user this user user public void
  • 加速代码 - 3D 数组

    我正在尝试提高我编写的一些代码的速度 我想知道从 3d 整数数组访问数据的效率如何 我有一个数组 int cube new int 10 10 10 我用价值观填充其中 然后我访问这些值数千次 我想知道 由于理论上所有 3d 数组都存储在内
  • Liferay ClassNotFoundException:DLFileEntryImpl

    在我的 6 1 0 Portal 实例上 带有使用 ServiceBuilder 和 DL Api 的 6 1 0 SDK Portlet 这一行 DynamicQuery query DynamicQueryFactoryUtil for
  • 操作错误不会显示在 JSP 上

    我尝试在 Action 类中添加操作错误并将其打印在 JSP 页面上 当发生异常时 它将进入 catch 块并在控制台中打印 插入异常时出错 请联系管理员 在 catch 块中 我添加了它addActionError 我尝试在jsp页面中打
  • Spring @RequestMapping 带有可选参数

    我的控制器在请求映射中存在可选参数的问题 请查看下面的控制器 GetMapping produces MediaType APPLICATION JSON VALUE public ResponseEntity
  • 十进制到八进制的转换[重复]

    这个问题在这里已经有答案了 可能的重复 十进制转换错误 https stackoverflow com questions 13142977 decimal conversion error 我正在为一个类编写一个程序 并且在计算如何将八进
  • 禁止的软件包名称:java

    我尝试从数据库名称为 jaane 用户名 Hello 和密码 hello 获取数据 错误 java lang SecurityException Prohibited package name java at java lang Class
  • Java按日期升序对列表对象进行排序[重复]

    这个问题在这里已经有答案了 我想按一个参数对对象列表进行排序 其日期格式为 YYYY MM DD HH mm 按升序排列 我找不到正确的解决方案 在 python 中使用 lambda 很容易对其进行排序 但在 Java 中我遇到了问题 f
  • 为什么HashMap不能保证map的顺序随着时间的推移保持不变

    我在这里阅读有关 Hashmap 和 Hashtable 之间的区别 http javarevisited blogspot sg 2010 10 difference Between hashmap and html http javar
  • 在mockito中使用when进行模拟ContextLoader.getCurrentWebApplicationContext()调用。我该怎么做?

    我试图在使用 mockito 时模拟 ContextLoader getCurrentWebApplicationContext 调用 但它无法模拟 here is my source code Mock org springframewo
  • 如何在桌面浏览器上使用 webdriver 移动网络

    我正在使用 selenium webdriver 进行 AUT 被测应用程序 的功能测试自动化 AUT 是响应式网络 我几乎完成了桌面浏览器的不同测试用例 现在 相同的测试用例也适用于移动浏览器 因为可以从移动浏览器访问 AUT 由于它是响
  • 玩!框架:运行“h2-browser”可以运行,但网页不可用

    当我运行命令时activator h2 browser它会使用以下 url 打开浏览器 192 168 1 17 8082 但我得到 使用 Chrome 此网页无法使用 奇怪的是它以前确实有效 从那时起我唯一改变的是JAVA OPTS以启用
  • 声明的包“”与预期的包不匹配

    我可以编译并运行我的代码 但 VSCode 中始终显示错误 早些时候有一个弹出窗口 我不记得是什么了 我点击了 全局应用 从那以后一直是这样 Output is there but so is the error The declared
  • 编译器抱怨“缺少返回语句”,即使不可能达到缺少返回语句的条件

    在下面的方法中 编译器抱怨缺少退货声明即使该方法只有一条路径 并且它包含一个return陈述 抑制错误需要另一个return陈述 public int foo if true return 5 鉴于Java编译器可以识别无限循环 https
  • 捕获的图像分辨率太大

    我在做什么 我允许用户捕获图像 将其存储到 SD 卡中并上传到服务器 但捕获图像的分辨率为宽度 4608 像素和高度 2592 像素 现在我想要什么 如何在不影响质量的情况下获得小分辨率图像 例如我可以获取或设置捕获的图像分辨率为原始图像分
  • JGit 检查分支是否已签出

    我正在使用 JGit 开发一个项目 我设法删除了一个分支 但我还想检查该分支是否已签出 我发现了一个变量CheckoutCommand但它是私有的 private boolean isCheckoutIndex return startCo

随机推荐

  • MySQL utf8mb4 字符集,用于存储emoji表情

    最近在做微信相关的项目 其中MySQL 要存储emoji表情 因此发现我们常用的utf8 字符集根本无法存储表情 网上有不少替代方案 本人还是采用了修改MySQL字符集的方案简单快捷 首先将我们数据库默认字符集由utf8 更改为utf8mb
  • Pandas分组与排序

    Grouping and Sorting 分组 agg 排序 经常需要将数据根据某个字段划分为不同的组 group 进行分析 然后对组里的数据进行特定的操作 pandas的 groupby 操作便是实现这一功能 groupby的过程就是将原
  • jquery的两种常用自动加载方法

    一 jquery JavaScript的三种常用自动加载方法 1 function jQuery 2 function 3 window nl ad function 加载的先后顺序 第一步 代码块1加载 是在css html 信息加载完毕
  • Scala环境配置完成,在命令行还是不能运行

    刚开始我以为是版本兼容的问题 所以下载了很多个版本 发现没用 我找了很久都不知道是什么原因 网上也没找到跟我一样的问题 偶然我发现是系统环境变量PATHEXT中缺少东西 在PATHEXT中添加 bat 然后就可以了
  • AIX系统安装

    1 选择安装介质 CD ROM 现有备份的安装系统 网络安装 Token Ring Ethernet FDDI U盘 服务器通电启动系统 在控制台显示器出现keyboard字符时 按对应的按钮 1 进入系统管理服务模式 SMS 2 指定控制
  • C语言中结构体初始化并清零的方法有几种?

    结构体初始化清零方法 在C语言中 结构体初始化并清零的方法有以下几种 手动赋值为0 结构体定义后在函数内手动将每个成员都赋值为0 例如 struct MyStruct int a char b float c struct MyStruct
  • vue页面基本组成

    作为编写过html的人 vue页面的基本组成是什么呢 如何快速入手vue呢 我来讲下自己的思路 简介 vue是一个前端框架 运行它需要下载node js 后台支撑 下载vs code 代码编辑器 来编辑代码 可配合eliment ui 上百
  • nodejs处理图片文件上传

    如果使用express框架的话 其内置模块就可以直接处理文件上传了 而不需要饱含额外的模块 express版本 3 4 4 1 使用bodyParser过滤器 并且指定上传的目录为public upload 注意这里的目录为相对于expre
  • PyQt5学习笔记--GridLayout、FormLayout和StackedLayout布局

    目录 1 GridLayout布局 2 FormLayout布局 3 StackedLayout布局 1 GridLayout布局 import sys from PyQt5 QtWidgets import class MyWindow
  • select、poll、epoll

    因为实际需要所致 我们不得不考虑在现有的开源 商用的应用服务器之外开发一个 有性能要求 有并发要求的服务端应用 从技术要求的角度来分析一下 用Java实现这件事情我们可能关注的知识层面 在整体上 可能需要我们从下面几个层面出发来考虑 1 在
  • windows多个不同java共存

    windows多个不同java共存 如图我电脑存在java1 8和15 使用时 我会存在工具支持的java版本不一样 有的工具要8才能使用有的工具需要11或者15以上java才能正常使用 于是为了方便快捷便写了这个多java版本共存 jav
  • 微服务SpringCloud

    什么是SpringCloud SpringCloud是由Spring提供的一套能够快速搭建微服务架构程序的框架集 SpringCloud本身不是一个框架 而是一系列框架的统称 SpringClound就是为了搭建微服务架构才出现的 有人将S
  • Linux如何查看系统时间

    文章目录 一 使用date命令查看系统时间 二 通过 var log syslog文件查看系统时间 三 通过 proc uptime文件查看系统运行时间 四 通过hwclock命令查看硬件时间 五 通过timedatectl命令设置系统时区
  • Python实现普通二叉树

    Python实现普通二叉树 二叉树是每个节点最多有两个子树的树结构 本文使用Python来实现普通的二叉树 关于二叉树的介绍 可以参考 https blog csdn net weixin 43790276 article details
  • MES系统是什么?MES系统的主要功能是什么?看完本文就知道

    MES系统是什么 MES系统是一套面向制造企业车间执行层的生产信息化管理系统 MES可以为企业提供包括制造数据管理 计划排程管理 生产调度管理 库存管理 质量管理 人力资源管理 工作中心 设备管理 工具工装管理 采购管理 成本管理 项目看板
  • PytorchCNN项目搭建 6--- 训练、验证CNN

    PytorchCNN项目搭建 6 训练 验证CNN 1 配置args cfg log 等 2 将数据集dataset经DataLoader变成dataloader 3 加载网络net 4 选择损失函数和优化器 5 训练网络 得到损失值 主函
  • 【qt】蒙版mask使用

    蒙版 mask 蒙版基本概念 在绘图软件中 蒙版类似于蒙在原始图片上的一块玻璃 即蒙版 然后我们再在这块玻璃上使用其他工具对图片进行修改 这样就不会破坏原始图片 而又能看到图片修改后的效果 蒙版通常是黑白色的 通常通过改变蒙版 玻璃 的灰度
  • node 加密解密模块_Node之加密与解密处理

    crypto模块概述 在Node js中 使用OpenSSL类库作为其内部实现加密与解密处理的基础手段 这是因为目前OpenSSL已经成为了一个经过严格测试的可靠的加密与解密算法的实现工具 在Node js中 OpenSSL类库被封装在cr
  • 真正解决Pandas写入excel的多sheet问题

    真正解决Pandas写入excel的多sheet问题 遇到需要利用pandas的to excel 在同一个Excel文件中 循环在不同的sheet中写入数据 但查阅大量资料 基本都无法利用for循环 在 sheet1 sheet2 shee
  • java中native的用法

    Java开发中会碰到声明为 native的方法 如 public native int hashCode 这是一个native方法 为什么存在native方法呢 Java不是完美的 Java的不足除了体现在运行速度上要比传统的C 慢许多之外