Java中的native方法的使用_native修饰方法-程序员宅基地

技术标签: Java  native方法  

1.关于native关键字

想必读者已经了解过native关键字了。这里笔者就大致囊括一下,被native关键字修饰的方法叫做本地方法,本地方法和其它方法不一样,本地方法意味着和平台有关,因此使用了native的程序可移植性都不太高。另外native方法在JVM中运行时数据区也和其它方法不一样,它有专门的本地方法栈。native方法主要用于加载文件和动态链接库,由于Java语言无法访问操作系统底层信息(比如:底层硬件设备等),这时候就需要借助C语言来完成了。被native修饰的方法可以被C语言重写。

2.使用native关键字

2.1 使用步骤

  • Java程序中声明native修饰的方法,类似于abstract修饰的方法,只有方法签名,没有方法实现。编译该java文件,会产生一个.class文件。
  • 使用javah编译上一步产生的class文件,会产生一个.h文件。
  • 写一个.cpp文件实现上一步中.h文件中的方法。
  • 将上一步的.cpp文件编译成动态链接库文件.dll。
  • 最后就可以使用System或是Runtime中的loadLibrary()方法加载上一步的产生的动态连接库文件了。

2.2 案例

为了更好理解,该案例的所有都在文件在 D:\JNI\ 目录下。

2.2.1 编写.java文件
public class HelloWorld{
    
    public native void h();//该方法和abstract修饰的方法一样,只有签名。
    
    static{
    
        System.loadLibrary("hello");//不写文件的后缀,程序会自动加上.dll的。
    }
    
    public static void main(String[] args){
    
        new HelloWorld().h();//调用
    }
}
2.2.2 编译.java文件

在CMD中编译该程序 javac HelloWorld.java ,就会产生一个HelloWorld.class文件。

2.2.3 获得.h文件

将第二步中产生的字节码文件,通过 javah -jni HelloWorld 就会产生一个HelloWorld.h文件。

我们用记事本打开HelloWorld.h文件

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

#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     HelloWorld
 * Method:    h
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_HelloWorld_h
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

可以看出,在HelloWorld.java文件中的h()方法已经变成了 JNIEXPORT void JNICALL Java_HelloWorld_h (JNIEnv *, jobject); ,方法名是原来的 包名_类名_方法名 。在该文件中还引用了 jni.h 文件。

2.2.4 编写hello.cpp文件

编写hello.cpp文件的方式有许多,可以利用Visual Studio软件,因为最后需要生成dll文件,因此在下载Visual Studio之前应该查一查版本是否能够生成自己电脑需要的dll版本(32位dll或64为dll)。这里下载的是vs2013,该版本既可以生成32的dll,由可以生成64位的dll。关于vs2013生成dll可以参考Visual Studio 2013生成64位dll

因为我们在第一步中调用的文件名称为hello,所以这里的.cpp文件必须为 hello.cpp 文件。这里笔者的文件如下:

// hello.cpp : 定义 DLL 应用程序的导出函数。
//

#include "stdafx.h"
#include "HelloWorld.h"

JNIEXPORT void JNICALL Java_HelloWorld_h(JNIEnv *, jobject) {
    
    printf("Hello! ");//打印信息
}

可以看出引入了 HelloWorld.h 文件,所以hello.cpp 文件应该和 HelloWorld.h文件在同一个目录下面。如果读者现在编译hello.cpp文件会报错 “jni.h”: No such file or directory 。在 HelloWorld.h 文件中我们引入了 jni.h文件,所以也应该把 jni.h 文件放到同一级目录下面,关于这个文件和相关的文件读者可以到JDK的安装目录下面的include下面查找,更多信息可以查看JDk、JRE、JVM的关系。还应该把 HelloWorld.h 文件中的 #include <jni.h> 改为 #include “jni.h” 。最后生成 hello.dll 文件就可以了

2.2.5 部署hello.dll文件

我们使用了 System.loadLibary(“hello”); 加载动态链接库,这个加载路径是按照java.libary.path进行查询的,读者可以根据System.getProperty(“java.libary.path”)验证,该路径就是环境变量中的path路径。网上有好多说直接把hello.dll仍在 C:\Windows\System32 路径下。不过笔者建议,先应该查看自己环境变量path的值,那么把hello.dll放到path中配置的第一个路径下。

2.2.6 运行HelloWorld.class文件

我们回到 D:/JNI 路径下,使用 java HelloWorld 就成功调用动态连接库了。
在这里插入图片描述
笔者的控制台上成功打印了hello!。笔者对这里加载的理解,就是利用反射机制,在运行的时候找到hello.dll文件并且解析,根据动态链接库中的文件名称创建出对象和方法,然后我们就可以利用对象调用方法了。上面的HelloWorld.java文件,创建动态链接库和调用方法都在同一个类中,这样的话一个只需要使用这个类的对象调用方法就可以通过编译和运行了。如果我们引入的是被人的.cpp文件,那么根据.cpp文件中的方法名,在需要的地方做适当调整就可以调用了。

参考文章:
自己实现一个native方法的调用
详解native方法的使用

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/shao_yc/article/details/106880947

智能推荐

了解BFC_b 'i jkfccfdd 。/-程序员宅基地

文章浏览阅读76次。在学习css盒子布局过程中,会出现盒子塌陷问题,在解决这些问题时,看到BFC的特性,并可以解决这方面的问题,本文是简单对BFC的总结。1、什么是BFC BFC 即 Block Formatting Contexts (块级格式化上下文),它属于上述布局模式的流动模型。是W3C CSS2.1规范中的一个概念,决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用。..._b 'i jkfccfdd 。/

java爬取双色球所有中奖号码历史数据-程序员宅基地

文章浏览阅读3.7k次。org.jsoup是一个用于解析、操作和遍历HTML文档的Java库。它提供了简单易用的API,使得开发者能够方便地从HTML中提取数据、修改HTML内容、进行选择器查询等操作。下面对org.jsoup的主要功能进行详细解释。

[ 云计算 | AWS 实践 ] 基于 Amazon S3 协议搭建个人云存储服务_s3存储安装-程序员宅基地

文章浏览阅读5.8k次,点赞55次,收藏42次。MinIO 是一个高性能的对象存储系统。它被设计为云原生存储系统的替代方案。事实上,其 API 与 Amazon S3 完全兼容;MinIO 也提供兼容阿里云等国内云厂商的 API,由于本文篇幅问题,在本博文中,只介绍亚马逊 AWS 与其关联的案例以及如何快速使用 MinIO。Minio 是 GlusterFS 创始人之一 Anand Babu Periasamy 发布新的开源项目。MinIO 从一开始就被设计为完全兼容 Amazon S3 存储 API 的替代方案。_s3存储安装

jackson出现错误 Unrecognized field,几种处理方法_unrecognized field "crspool" (class com.ctyun.prob-程序员宅基地

文章浏览阅读5.5w次,点赞4次,收藏8次。错误堆栈信息如下:org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "HPYS" (Class com.traffic.entity.BusBaseInfo), not marked as ignorable at [Source: java.io.StringReader@76c5f_unrecognized field "crspool" (class com.ctyun.probe.cmdbinfo), not marked as

《动手学习深度学习》第二天_y.backward() 出错 动手学深度学习-程序员宅基地

文章浏览阅读185次。正式开始啦!!!线性回归1、回归与分类的差别最开始接触机器学习的时候,回归与分类就困扰了好久,就像书中说的那样回归的输出是连续的,就像天气的变化,在一定时间内都是连续变化的,不会说一下子温度就会从20度到30度,并且只要单位够小,从20度到21度之间可以划分为无数个不同度数。同样拿天气来说,分类预测明天是否会下雨,我们会提前给定几个状态,下雨还是不下雨,又或者说阴天,就算加上什么雷阵雨的,也是可数的几个状态。2、线性回归原理书中的介绍已经够清楚了,就是通过线性模型来找到输入与输出之前的关系。这里还_y.backward() 出错 动手学深度学习

Unity3D_向量(Vector3)数学基础_unity vector3=-程序员宅基地

文章浏览阅读7.5w次,点赞59次,收藏264次。向量(Vector3)在虚拟的游戏世界中,3D数学决定了游戏,如何计算和模拟出开发者以及玩家看到的每一帧画面。学习基础的3D数学知识可以帮主用户对游戏引擎产生更深刻的了解。向量定义:既有大小又有方向的量叫做向量。在空间中,向量用一段有方向的线段来表示。应用十分广泛,可用于描述具有大小和方向两个属性的物理量,例如物体运动的速度、加速度、摄像机观察方向、刚体受到的力等都是向量。因此向量是物理、动..._unity vector3=

随便推点

公司感染勒索病毒怎么办 怎样及时补救?-程序员宅基地

文章浏览阅读2.3w次。什么是勒索病毒勒索病毒,简单来说就是黑客用来劫持用户数据资料,索取巨额赎金的武器。因为对企业用户造成的损失更加巨大,勒索病毒一出现就引起了广大企业用户以及安全厂商的高度重视。这种病毒主要通过漏洞、邮件和广告推广进行传播,利用各种加密算法对文件进行加密,必须拿到密钥才有可能破解,从而向受害者索要数额不等的赎金后才予以解密。该病毒性质恶劣、危害极大,变种类型非常快,对常规的杀毒软件都具有免疫性,一...

Nginx 开启 IPv6 Nginx 开启 IPv6 SSL_nginx 支持ipv6版本-程序员宅基地

文章浏览阅读2.3k次,点赞2次,收藏5次。Nginx 开启IPv6,Nginx 开启IPv6 SSL,IPv6支持http,IPv6支持https_nginx 支持ipv6版本

空间关系_空间数据库touch,inside关系-程序员宅基地

文章浏览阅读3.2k次。基于维度扩展九交模式(Dimensionally Extended 9-Intersection Model,DE-9IM),MapGuide定义了如表8-3所示的11种空间关系,其中8种是OGC简单要素规范所定义的空间关系,另外3种FDO中自定义的空间关系。 空间关系中文名称OGC标准解释Contains_空间数据库touch,inside关系

Vmware虚拟机安装Ubuntu 18.04.2 LTS(长期支持)版本+VMware tools安装总结_虚拟机怎么打开usr文件夹-程序员宅基地

文章浏览阅读1.8k次,点赞2次,收藏6次。Vmware虚拟机安装Ubuntu 18.04.2 LTS(长期支持)版本+VMware tools安装可参考如下方法,不再赘述:http://www.cnblogs.com/Alier/p/6337151.html下面就安装过程中的注意事项和遇到的问题进行总结。在输入sudo ./vmware-install.pl后,再输入密码,会遇到很多询问,截图如下。其中, “ifconfig”的解决办..._虚拟机怎么打开usr文件夹

Ardunio开发ESP8266 中断问题_arduino esp8266 定时器中断-程序员宅基地

文章浏览阅读4.7k次,点赞16次,收藏55次。按键中断代码一直在找ESP8266的按键中断代码,大部分格式如下:const byte interruptPin = 0; //NodeUMCU 按键volatile byte interruptCounter = 0;int numberOfInterrupts = 0; void setup() { Serial.begin(115200); pinMode(interruptPin, INPUT_PULLUP); attachInterrupt(digitalPinT_arduino esp8266 定时器中断

css -- ie兼容写法_css ie兼容写法-程序员宅基地

文章浏览阅读1.5k次。简单的记录一下css兼容ie的写法:color:#FF5246; //一般浏览器识别color:#acacac\9; //IE8,IE9及以上版本识别*color:#3c3c3c; //IE7识别_color:#f4f4f4; //IE6识别在正常的css代码后加 ‘/9’ 只有在IE浏览器才能识别,其它浏览器会自动忽略,因此通过此条语句来区分是ie浏览器还是其它浏览器然后因为ie版本问题,我们需要兼容一下低版本的ie7 / ie6因此在通过*color_css ie兼容写法