前言

今天看AndFix实现时,核心方法之ReplaceMethod方法是一个native方法,之前并没有遇到过,所以在此整理记录。

native的作用

总而言之:native是与C++联合开发的时候用的!使用native关键字说明这个方法是原生函数,也就是这个方法是用C/C++语言实现的,并且被编译成了DLL,由java去调用。

native 是用做java 和其他语言(如c++)进行协作时使用的,也就是native 后的函数的实现不是用java写的。

既然都不是java,那就别管它的源代码了,我们只需要知道这个方法已经被实现即可。

native的意思就是通知操作系统, 这个函数你必须给我实现,因为我要使用。 所以native关键字的函数都是操作系统实现的, java只能调用。

java是跨平台的语言,既然是跨了平台,所付出的代价就是牺牲一些对底层的控制,而java要实现对底层的控制,就需要一些其他语言的帮助,这个就是native的作用了

JNI简介

native方法是通过java中的JNI实现的。JNI是Java Native Interface的 缩写。从Java 1.1开始,Java Native Interface (JNI)标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。

JNI一开始是为了本地已编译语言,尤其是C和C++而设计 的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。

目前java与dll交互的技术主要有3种:jni,jawin和jacob。

目前功能性而言:jni >> jawin > jacob,其大致的结构如下图:

jni_jawin_jacob

windows,基于native的PE结构,windows的jvm基于native结构,Java的应用体系构建于jvm之上。jvm通过加载此jni程序间接调用目标原生函数。

image

JNI的生成步骤——Mac版

编写带有native声明的方法的java类,生成.java文件

使用javac命令编译所编写的java类,生成.class文件

使用javah -jni java类名生成扩展名为h的头文件,也即生成.h文件

使用C/C++(或者其他编程想语言)实现本地方法,创建.h文件的实现,也就是创建.cpp文件实现.h文件中的方法

将C/C++编写的文件生成动态连接库,生成jnilib文件

JNI实例

接下来我们按照上述步骤一个一个来生成JNI实例

1.编写带有native声明的java类,HelloWorld.java

public class HelloWorld {

public native void sayHelloWorld(); //申明一个native方法

static{

System.loadLibrary("HelloWorldImpl"); //装入动态链接库,"HelloWorldImpl"是装入动态链接库的名称

}

public static void main(String[] args){

HelloWorld helloWorld = new HelloWorld();

helloWorld.sayHelloWorld();

}

}

2.使用javac生成HelloWorld.class

javac HelloWorld.java

3.使用javah -jni java类生成扩展名为h的头文件

javah -jni HelloWorld

此处需要注意的是,我们应该在包名的根目录下执行,因为生成的文件的文件名需要引用包目录。不然就会报找不到类文件的错误

生成com_think_jni_HelloWorld.h文件

/* DO NOT EDIT THIS FILE - it is machine generated */

#include

/* Header for class com_think_jni_HelloWorld */

#ifndef _Included_com_think_jni_HelloWorld

#define _Included_com_think_jni_HelloWorld

#ifdef __cplusplus

extern "C" {

#endif

/*

* Class: com_think_jni_HelloWorld

* Method: displayHelloWorld

* Signature: ()V

*/

JNIEXPORT void JNICALL Java_com_think_jni_HelloWorld_displayHelloWorld

(JNIEnv *, jobject);

#ifdef __cplusplus

}

#endif

#endif

这里我们可以这样理解:这个h文件相当于我们在java里面的接口,这里声明了一个 Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject);方法,然后在我们的本地方法里面实现这个方法,也就是说我们在编写C/C++程序的时候所使用的方法名必须和这里的一致

4使用C/C++实现本地方法

创建HelloWorldImpl.cpp,代码如下所示:

#include "jni.h"

#include "com_think_jni_HelloWorld.h"

#include

JNIEXPORT void JNICALL Java_com_think_jni_HelloWorld_displayHelloWorld(JNIEnv *env,jobject obj){

printf("Hello World!\n");

return;

}

5 将本地方法编写的文件生成动态链接库

gcc -I/Library/Java/JavaVirtualMachines/[根据装的jdk版本来定]/Contents/Home/include/ -dynamiclib HelloWorldImpl.cpp -o libhell.jnilib

但是会出现运行这个命令报错

file not found

我们找到这个文件在

/Library/Java/JavaVirtualMachines/[根据安装的jdk版本来定]/Contents/Home/include/darwin/

这个目录下,所以我们再链接该目录到以上命令中

gcc -I/Library/Java/JavaVirtualMachines/jdk1.8.0_71.jdk/Contents/Home/include/ -I/Library/Java/JavaVirtualMachines/jdk1.8.0_71

.jdk/Contents/Home/include/darwin/ -dynamiclib HelloWorldImpl.cpp -o libhell.jnilib

最终成功生成libhell.jnilib

6 运行可执行文件

把上述文件放在同一个文件夹后,执行

java HelloWorld

即可看到

image

java native 例子_Java native方法以及JNI实践相关推荐

  1. java面向对象例子_Java面向对象及方法实例讲解

    第一节方法 1.1定义 定义:封装了能够完成特定功能的代码块,是程序编程中的一种功能实现单元: 1.2语法 修饰符  返回值类型   方法名(参数列表) { 方法体: } 例子: 1 public s ...

  2. java.equal例子_Java中的== 和equals()方法详解与实例

    Java中的== 和equals()方法: Java中的数据类型,可分为两类: 1.基本数据类型,也称原始数据类型. byte,short,char,int,long,float,double,boo ...

  3. java gc 例子_Java 中, 为什么一个对象的实例方法在执行完成之前其对象可以被 GC 回收?...

    收到好多邀请-泻药泻药.其中有好些感觉是想来吃瓜的. 所以请让我先跑个题,为吃瓜群众献上几个传送门: private static void newSingleThreadPool() { Execu ...

  4. java native堆_Java Native Memory比堆更快吗?

    执行IO时,直接内存更快,因为它可以避免一个数据副本.但是,对于95%的申请,您不会注意到差异. 您可以将数据存储在直接内存中,但是它不会比存储数据POJO快. (或安全,可读或可维护)如果您担心GC ...

  5. java boolean例子_java.lang.Boolean.booleanValue()方法实例

    全屏 java.lang.Boolean.booleanValue()返回该Boolean对象作为一个布尔原始值. 声明 以下是java.lang.Boolean.booleanValue()方法的声 ...

  6. java 双向链表例子_Java双向链表按照顺序添加节点的方法实例_Java_软件编程

    分析过程: 首先需要比较待添加的节点编号与已有的节点编号的大小,若待添加的节点编号已经存在,则不能加入.为防止出现空指针的情况,需要对节点的位置进行判断. 示例代码: package linkedli ...

  7. java gc 例子_Java GC.drawImage方法代码示例

    import org.eclipse.swt.graphics.GC; //导入方法依赖的package包/类 void paintElement(PaintEvent e) { GC g = e.g ...

  8. java日历教程_JAVA Calendar方法使用基础教程详解

    究竟什么是一个 Calendar 呢?中文的翻译就是日历,那我们立刻可以想到我们生活中有阳(公)历.阴(农)历之分.它们的区别在哪呢? 比如有: 月份的定义 – 阳`(公)历 一年12 个月,每个月的 ...

  9. java代码例子_Java与C++两大语言比较

    Java Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承.指针等概念,因此Java语言具有功能强大和简单易用两个特征.Java语言作为静态面向对象编程 ...

最新文章

  1. 面向对象分析和设计的几个关键步骤_(豁然开朗)《面向对象分析与设计》读书笔记 (4)- 分类...
  2. linux 网络状态表 /proc/net/tcp 各项参数说明
  3. 强连通分量(Strongly_Connected_Components)
  4. Laravel 某个字段更新失败的原因
  5. decode 大于比较 小于_6 燃气输配系统6.3 压力不大于1.6Mpa的室外燃气管道城镇燃气设计规范 GB500282006(2020修订版)...
  6. django-url映射给函数给默认值
  7. java中用Executor代替Thread的四大理由
  8. ibatis的ibatorForEclipse的安装与配置和ibator的错误日志查看
  9. vue style.css,vue * !!vue-style-loader!css-loader?
  10. MISRA C指导指南解读系列1(MISRA C是什么)
  11. PDF编辑软件哪个好 如何裁剪PDF文件页面
  12. 信而泰 X-Snapper测试系统,助力家庭路由器IPv6支持度测试
  13. IP签名档美化版api源码PHP
  14. 【报告分享】2021全球自由行报告-中国旅游研究院马蜂窝(附下载)
  15. 3GPP TS 23501-g51 中英文对照 | 4.2.8 Support of non-3GPP access
  16. 统计学 一元线性回归
  17. Vista和DirectX 10(转载)
  18. 通信电子电路(二十一) 第二章 知识点总结+作业分析
  19. UE4平移视图方向更改
  20. 双系统[mac os][win]当中,分区导致进不去苹果分区解决办法

热门文章

  1. JAVA vs C++之速度—
  2. 清空数据库错误:因为该表正由 FOREIGN KEY 约束引用 解决办法
  3. 学完java后学编译原理_一个资深程序员对Java初学者的学习思维路线建议
  4. mysql-front权限管理_mysql 用户及权限管理 小结
  5. java Date days_Java中的LocalDate plusDays()方法
  6. Java黑皮书课后题第6章:6.37(格式化整数)编写一个测试程序,提示用户输入一个数字以及宽度,显示通过调用format方法返回的字符串
  7. Java黑皮书课后题第5章:**5.27(显示闰年)编写程序,显示从101到2100期间所有闰年,每行显示10个。数字之间用一个空格字符隔开,同时显示这期间闰年的数目
  8. Python的3种执行方式
  9. AbstractFactoryPattern(23种设计模式之一)
  10. scenejs的一点Cameras小笔记