美文网首页
★02.入门

★02.入门

作者: iDragonfly | 来源:发表于2017-07-03 19:41 被阅读0次

    简介

    • 本节示例怎么使 Java应用程序 通过 JNI 调用 C语言 输出Hello World!

    流程

    1. 创建一个HelloWorld.java文件并声明原生方法。
    2. 使用 javac 编译HelloWorld.java,生成HelloWorld.class文件。
    3. 使用 javah 生成C头文件HelloWorld.h,该头文件包含了原生函数实现的原型。
    4. 新建文件HelloWorld.c并按照HelloWorld.h中声明的原生函数原型实现原生代码。
    5. HelloWorld.c构建成为一个原生库,生成HelloWorld.dll或者HelloWorld.so
    6. 使用 Java 运行HelloWorld程序,HelloWorld.classHelloWorld.dll/so会在运行时被加载。
    JNI Hello World 示意图

    HelloWorld示例

    1. 创建HelloWorld.java

    代码

    public class HelloWorld {
        static {
            // "HelloWorld" 表明载入HelloWorld.dll
            System.loadLibrary("HelloWorld");
        }
    
        public static void main(String[] args) {
            new HelloWorld().print();
        }
    
        private native void print();
    }
    

    解说

    • 上述代码主要包含三个部分:
      1. 一个静态代码块,用来加载 动态链接库
      2. 一个主函数作为 Java应用程序 入口,并在主函数中调用print
      3. 一个原生函数print的声明,由原生代码实现。
    • 包含原生代码的 动态链接库 一定要提前加载。
    • print函数声明中的native修饰符表示该函数是使用其他语言实现的。

    2. 生成HelloWorld.class

    • 编译产生HelloWorld.class

    3. 使用CLion创建C/C++项目

    • 保证 CLion 使用的是 MinGW-w64 而不是 MinGW-32
    • 设置JAVAHOME环境变量,指向 jdk 目录。
    • 通过CMakeList.txt设置 JNI 包含目录。
    • 通过CMakeList.txt设置构建完毕后自动复制 DLLJava 项目目录下。
    • CMakeList.txt文件参考,
    cmake_minimum_required(VERSION 3.7)
    project(JNI_c)
    
    set(CMAKE_C_STANDARD 11)
    
    # 相当于 SOURCE_FILES = "HelloWorld.h HelloWorld.c"
    set(SOURCE_FILES HelloWorld.h HelloWorld.c)
    add_library(JNI_c SHARED ${SOURCE_FILES})
    
    include_directories($ENV{JAVAHOME}/include)
    include_directories($ENV{JAVAHOME}/include/win32)
    
    # 设置输出DLL的名字前缀
    set_target_properties(JNI_c PROPERTIES PREFIX "")
    # 设置输出DLL的名字,此处输出HelloWorld.dll
    set_target_properties(JNI_c PROPERTIES OUTPUT_NAME "HelloWorld")
    
    # 构建完后复制DLL到指定目录
    add_custom_command(TARGET JNI_c POST_BUILD                     # JNI_c是项目名称
            COMMAND ${CMAKE_COMMAND} -E copy_if_different
            "$<TARGET_FILE_DIR:JNI_c>/HelloWorld.dll"           # input dir
            "C:/ProgramProjects/Java/JNI")                         # output dir
    

    4. 生成HelloWorld.h

    1. 配置 IDEA 中生成头文件规则(已配置则跳过)

    1. File -> Settings -> External Tools。
    2. 点击 “+” 按钮。
      1. Name : 生成头文件
      2. Group : JNI
      3. Options : 全部勾选。
      4. Show in : 全部勾选。
      5. Program : $JDKPath$\bin\javah.exe
      6. Parameters : -jni -v -d $FileDir$ $FileClass$$FileDir$表示输出目录,将$FileDir$设置为 CLion 项目目录。
      7. Working directory : $SourcepathEntry$
    3. 点击确定。

    2. 生成

    1. 选择对应的java文件。
    2. 右键 -> JNI -> Generate Header File。
    3. $FileDir$对应的目录里生成了HelloWorld.h

    3. 解说HelloWorld.h文件

    代码

    /*
     * Class:     HelloWorld
     * Method:    print
     * Signature: ()V
     */
    JNIEXPORT void JNICALL Java_HelloWorld_print
      (JNIEnv * , jobject);
    

    解说

    • 注释部分:
      • Class :函数来自的那一个类的名字。
      • Method :这个函数的名字。
      • Signature :这个函数的签名。
        • ()V:函数的签名为void ()
        • (IFC)D:这个函数的double (int, float, char)
    • 代码部分:
      • void:原方法的返回值。
      • JNIEnv *:一个JNIEnv接口指针。
      • jobjectHelloWorld对象本身,有点像 C++ 中的this指针。

    5. 实现HelloWorld.c

    #include <jni.h>
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    /*
     * Class:     HelloWorld
     * Method:    print
     * Signature: ()V
     */
    JNIEXPORT void JNICALL Java_HelloWorld_print(JNIEnv * env, jobject obj) {
        printf("Hello World!\n");
    }
    
    #ifdef __cplusplus
    }
    #endif
    

    5. 生成动态链接库并运行

    • Clion 中构建项目,生成 DLL 到对应目录。
    • 设置 IDEA 中的 Run/Debug Configurations
      • VM Options 设置为-Djava.library.path=C:\ProgramProjects\Java\JNI\
    • 运行程序。

    相关文章

      网友评论

          本文标题:★02.入门

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