Java中的native方法实现(Java混用C/C++)

作者: 53b3f4658edc | 来源:发表于2017-12-04 18:59 被阅读9次

    前言

    • native关键字说明其修饰的方法是一个原生态方法,方法对应的实现不是在当前文件,而是在用其他语言(如C和C++)实现的文件中。Java语言本身不能对操作系统底层进行访问和操作,但是可以通过JNI接口调用其他语言来实现对底层的访问。
    • JNI是Java本机接口(Java Native Interface),是一个本机编程接口,它是Java软件开发工具箱(Java Software Development Kit,SDK)的一部分。JNI允许Java代码使用以其他语言编写的代码和代码库。Invocation API(JNI的一部分)可以用来将Java虚拟机(JVM)嵌入到本机应用程序中,从而允许程序员从本机代码内部调用Java代码。不过,对Java外部的调用通常不能移植到其他平台,在applet中还可能引发安全异常。实现本地代码将使您的Java应用程序无法通过100%纯Java测试。

    实现步骤

    1.书写一个Java类

    public class HelloWorld {
        // 使用关键字native来声明方法
        public native void displayInfor(String name);
        
        // 加载动态链接库 
        static {
            System.load("/Users/mac/Desktop/HelloWorldImpl.dylib");
        }
        
        public static void main(String[] args) {
            HelloWorld helloWorld = new HelloWorld();
            helloWorld.displayInfor("冯强");
        }
    }
    

    其中public native void displayInfor(String name);,声明了一个本地方法,有参数name,返回类型void。
    System.load("/Users/mac/Desktop/HelloWorldImpl.dylib");表示加载一个本地动态链接库。

    2.使用下javac命令编译该文件:

    Macs-MacBook-Pro:Desktop mac$ javac HelloWorld.java 
    

    我们会看到生成了一个HelloWorld.class文件


    微信公众号:JavaWeb架构师

    3.使用javah命令处理HelloWorld.class文件

    Macs-MacBook-Pro:Desktop mac$ javah -jni HelloWorld
    

    这时候我们可以看到生成了一个HelloWorld.h文件:


    图片.png

    4.打开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:    displayInfor
     * Signature: (Ljava/lang/String;)V
     */
    JNIEXPORT void JNICALL Java_HelloWorld_displayInfor
      (JNIEnv *, jobject, jstring);
    
    #ifdef __cplusplus
    }
    #endif
    #endif
    

    其中:

    JNIEXPORT void JNICALL Java_HelloWorld_displayInfor
      (JNIEnv *, jobject, jstring);
    

    就是Java代码中对应的native方法,命名格式是 Java_类名_方法名(JNIEnv,jobject,这里是参数)。

    5.修改HelloWorld.h文件中的#include <jni.h>为#include "jni.h"

    6.拷贝/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/include下面的jni.h到与HelloWorld.h相同的目录下


    微信公众号:JavaWeb架构师

    7.新建一个HelloWorld.cpp文件,实现其中的JNIEXPORT void JNICALL Java_HelloWorld_displayInfor
    (JNIEnv *, jobject, jstring);方法

    // 引入刚刚通过class文件生成的.h文件
    #include "HelloWorld.h"
    #include <stdio.h>
    #include <iostream>
    
    using namespace std;
    /*
     * Class:     HelloWorld
     * Method:    displayInfor
     * Signature: (Ljava/lang/String;)V
     */
    JNIEXPORT void JNICALL Java_HelloWorld_displayInfor
    (JNIEnv * env, jobject obj, jstring name) {
        cout<<"你好,"<<env->GetStringUTFChars(name, NULL)<<endl;
    }
    
    微信公众号:JavaWeb架构师

    8.使用g++处理HelloWorld.cpp生成动态链接库

    Macs-MacBook-Pro:Desktop mac$ g++ -dynamiclib -o HelloWorldImpl.dylib HelloWorld.cpp 
    
    微信公众号:JavaWeb架构师

    9.复制HelloWorldImpl.dylib文件的地址,放入到java文件中

    System.load("/Users/mac/Desktop/HelloWorldImpl.dylib");
    

    10.最终的文件如下:


    微信公众号:JavaWeb架构师

    11.运行Java程序

    Macs-MacBook-Pro:Desktop mac$ java HelloWorld
    你好,冯强
    
    微信公众号:JavaWeb架构师

    其它

    • 源码下载
    关注下方公众号,回复:jni.code
    
    完整教程PDF版本下载

    相关文章

      网友评论

        本文标题:Java中的native方法实现(Java混用C/C++)

        本文链接:https://www.haomeiwen.com/subject/yynxixtx.html