【java】一篇搞清楚JNI 本地接口

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

  IOUtil中加载了这些动态库,

JDK C实现 Java加载动态库+ native接口方法 上层IO、网络操作依赖调用

public class IOUtil {
    /**
     * 空方法,触发动态库加载
     */
    public static void load() { }

    static {
        java.security.AccessController.doPrivileged(
                new java.security.PrivilegedAction<Void>() {
                    public Void run() {
                        System.loadLibrary("net");
                        System.loadLibrary("nio");
                        return null;
                    }
                });

        initIDs();

        IOV_MAX = iovMax();
    }


public static native void configureBlocking(FileDescriptor fd,
                                            boolean blocking)
}

混合编程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函数,可

发布了92 篇原创文章 · 获赞 14 · 访问量 5825

猜你喜欢

转载自blog.csdn.net/sarafina527/article/details/103667733