JNI能让Java代码在Java虚拟机里调用其他编程语言(例如C、C++)写的应用或库,且不会影响任何Java虚拟机的实现。

什么时候用JNI?

1、应用程序所需的平台相关功能,标准的Java类库不支持时。

2、已经有一个用其他语言写的库,想要复用时。

3、想使用一些低级别的语言(例如汇编)实现部分关键代码时。

JNI问题

1、对开发者的要求更高。

2、丧失可移植性。

例子(C语言,on Mac)

1、添加声明为native的方法。

package nativetest;

public class CaculatorInC {

    //加法
public static native int add(int a, int b);
}

2、编译成h文件

有包名,直接这样就可以编译成h文件。(不然会报找不到类文件)

javah nativetest.CaculatorInC

没包名,先编译成class

javac xxx.java
javah xxx

生成的h文件内容

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class nativetest_CaculatorInC */ #ifndef _Included_nativetest_CaculatorInC
#define _Included_nativetest_CaculatorInC
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: nativetest_CaculatorInC
* Method: add
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_nativetest_CaculatorInC_add
(JNIEnv *, jclass, jint, jint); #ifdef __cplusplus
}
#endif
#endif

3、编写自己c文件

可以查看生成后的h文件,实现里面的方法。

#include "jni.h"
#include "nativetest_CaculatorInC.h" //#include otherheaders JNIEXPORT jint JNICALL Java_nativetest_CaculatorInC_add
(JNIEnv *env, jclass object, jint a, jint b){
return a + b;
}

4、将c文件编译成动态链接库

gcc -dynamiclib -I /Library/Java/JavaVirtualMachines/jdk1..0_45.jdk/Contents/Home/include/ *.c -o libcaculator.jnilib

注意可能会报,jni.h或jni_md.h文件不存在。

处理方法:

1、找到jdk的位置(/usr/libexec/java_home -V),编译命令带上“xxx/Contents/Home/include”的目录,如上。

2、把“xxx/Contents/Home/include/darwin”的目录里jni_md.h文件复制到include目录。

5、测试

package nativetest;

import nativetest.CaculatorInC;

public class Test {
static {
//System.setProperty("java.library.path", ".");
System.load("/Users/lufeng/Documents/project/java-workspace/java-demo/src/libcaculator.jnilib"); // 载入本地库
} public static void main(String[] args) {
System.out.println(CaculatorInC.add(1, 2));
}
}

参考文献

https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/intro.html#java_native_interface_overview

Java Native Interface(JNI)的更多相关文章

  1. 【详解】JNI (Java Native Interface) (二)

    案例二:传递参数给C代码,并从其获取结果 注:这里传递的参数是基本类型的参数,在C代码中有直接的映射类型. 此案例所有生成的所有文件如下: (1)编写案例二的Java代码,如下: 这里我们定义了一个n ...

  2. 【详解】JNI (Java Native Interface) (四)

    案例四:回调实例方法与静态方法 描述:此案例将通过Java调用的C语言代码回调Java方法. 要想调用实例对象的方法,需要进行以下步骤: 1. 通过对象实例,获取到对象类的引用  => GetO ...

  3. 【详解】JNI (Java Native Interface) (三)

    案例三:C代码访问Java对象的实例变量   获取对象的实例变量的步骤: 1. 通过GetObjectClass()方法获得此对象的类引用 2. 通过类引用的GetFieldID()方法获得实例变量的 ...

  4. Java Native Interface Specification(JNI)

    Java Native Interface Specification(JNI) 使用场景: 需要的功能,标准的java不能提供 有了一个用其他的语言写好的工具包,希望用java去访问它 当需要高性能 ...

  5. Java Native Interface 六JNI中的异常

    本文是<The Java Native Interface Programmer's Guide and Specification>读书笔记 在这里只讨论调用JNI方法可能会出现的异常, ...

  6. Java Native Interface 五 JNI里的多线程与JNI方法的注册

    本文是<The Java Native Interface Programmer's Guide and Specification>读书笔记 JNI里的多线程 在本地方法里写有关多线程的 ...

  7. Java Native Interface 四--JNI中引用类型

    本文是<The Java Native Interface Programmer's Guide and Specification>读书笔记 JNI支持将类实例和数组类型(如jobjec ...

  8. Java Native Interface 二 JNI中对Java基本类型和引用类型的处理

    本文是<The Java Native Interface Programmer's Guide and Specification>读书笔记 Java编程里会使用到两种类型:基本类型(如 ...

  9. Java Native Interface 基于JNI的嵌入式手机软件开发实例

    1.通过JNI和c/c++的库组件.其他代码交互 2.java和c不能互通的原因时数据类型问题 Introduction https://docs.oracle.com/javase/8/docs/t ...

随机推荐

  1. [Linux] deepin安装node

    安装git sudo apt-get install git git安装 安装node和npm 先下载node node下载 下载完之后将node解压的desktop,然后将文件夹更改为node 之后 ...

  2. FMDB源码解析

    上一篇博客讲述SQLite的使用,本篇将讲述FMDB源码,后面也会讲解SQLite在使用与FMDB的区别.本篇读下来大约20-30分钟,建议大家先收藏一下. FMDB是以OC方式封装SQLite中C语 ...

  3. Url的Base64编码以及解码

    Base64可以将二进制转码成可见字符方便进行http传输,但是base64转码时会生成“+”,“/”,“=”这些被URL进行转码的特殊字符,导致两方面数据不一致.我们可以在发送前将“+”,“/”,“ ...

  4. Ubuntu 18.1远程登录服务器--ssh的安装

    默认的Ubuntu 18.1桌面版没有安装ssh远程登录服务: 打开"终端窗口",输入"sudo apt-get update"-->回车-->&q ...

  5. mongodb "Element '{0}' does not match any field or property of class" 异常的解决方法

    在序列化的对象上增加 [BsonIgnoreExtraElements]

  6. php截取中文字符串无乱码的方法

    利用php内置方法mb_substr截取中文不乱码,使用起来非常简单 <?php $str = '我喜欢laravel or yii2'; echo mb_substr($str, 0, 1, ...

  7. Python中的特殊属性与方法

    模块的特殊属性 __doc__ 模块的说明文档 __all__ 指明模块希望被使用的属性.类和方法 __file__ 模块所在路径 类的特殊属性 __slots__ 限制类的实例允许添加的属性,是一个 ...

  8. Vue Document

    目录 VUE笔记 环境搭建 Vue学习笔记 1.Vue指令 VUE笔记 环境搭建 node -v npm -v npm i -g cnpm --registry=https://registry.np ...

  9. 使用mybatis开发dao方法

    使用mybatis开发dao的时候, 主要涉及到SqlSessionFactoryBuilder.SqlSessionFactory.SqlSession 这三个类 现在将这三个类的使用方法简单的说下 ...

  10. JDK和Tomcat安装

    JDK安装: 1,选择安装位置,其余默认安装,安装两次,一个是JDK,一个是JRE,安装在两个文件夹中. 2,配置环境变量: 1,新建一个变量,变量名:JAVA_HOME,变量值:C:\Program ...