1.概念
JNI(Java Native Interface)java本地接口,java声明一个native方法可以调用操作系统或者C/C++编译的动态库的方法实现。
通常用于与C/C++混合开发,比如有底层基础计算类库是C/C++的,又需要Java做WEB或者其它功能,Java提供的这一机制可以解决这一类问题。
此外,我们都知道java语言实现是没有办法直接操纵内存、文件、网络、锁等,所以JDK底层很多都是用C去实现,通过JNI去调用,如IOUtil C实现,这些实现编译后在/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre/lib下,
2.JDK demo
JDK C实现 | Java加载动态库+ native接口方法 | 上层IO、网络操作依赖调用 |
|
混合编程Demo
1、在Java中声明native()方法,然后编译; 2、用javah产生一个.h文件; 3、写一个.cpp文件实现native导出方法,其中需要包含第二步产生的.h文件(注意其中又包含了JDK带的jni.h文件); 4、将第三步的.cpp文件编译成动态链接库文件;拷贝到/Library/Java/Extensions 5、在Java中用System.loadLibrary()方法加载第四步产生的动态链接库文件,这个native()方法就可以在Java中被访问了。
1.写java代码,写native空实现方法
package jdk.jni;
public class HelloNative {
static
{
System.loadLibrary("HelloNative"); //加载库
}
/**
* native 关键字告诉编译器(其实是JVM)调用的是该方法在外部定义,这里指的是C。
*/
public static native void sayHello();
@SuppressWarnings("static-access")
public static void main(String[] args)
{
sayHello();
}
}
2.生成c h头文件
进入${项目目录}/target/classes,javah jdk.jni.HelloNative,由于我的java类放在了jdk.jni包下,跟java命令一样javah需要带上包名,
生成了一个jdk_jni_HelloNative.h 头文件
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class jdk_jni_HelloNative */
#ifndef _Included_jdk_jni_HelloNative
#define _Included_jdk_jni_HelloNative
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: jdk_jni_HelloNative
* Method: sayHello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_jdk_jni_HelloNative_sayHello
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
3.写C实现
#include "jni.h"
#include "jdk_jni_HelloNative.h"
#include <stdio.h>
JNIEXPORT void JNICALL Java_jdk_jni_HelloNative_sayHello(JNIEnv *env,jobject obj){
printf("Hello World!\n");
return;
}
4.编译成动态连接库文件
gcc -dynamiclib -I /Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/include HelloWorldImpl.c -o libhello.jnilib
并将其拷贝到/Library/Java/Extensions
5.执行main函数,可