• Java(97)Java的JNI学习(一)


    1、JNI介绍

    JNI是Java Native Interface的英文缩写,意为Java本地接口。为了方便Java调用c、c++等本地代码所封装的一层接口。Java的优点是跨平台,但是作为优点的同时,其在本地交互的时候编程就有了缺点,Java的跨平台特性导致其本地交互的能力不够强大,一些和操作系统相关的特性Java无法完成(Java编写底层的应用较难实现),于是Java提供了JNI专门用于和本地代码交互(C/C++开发任何和系统相关的程序和类库),这样就增强了Java语言的本地交互能力。

    2、Java通过JNI调用C代码

    先学习一个最简单的例子HelloWorld!

    最简单的Java通过JNI调用C代码的步骤:

    1、在Java类中声明一个native的方法

    2、使用Javah命令生成包含native方法声明的C头文件

    3、按照生成的C/C++头文件来写C源文件

    4、将C源文件编译成动态连接库(dll/SO)

    5、把dll/so文件加入PATH环境变量下

    6、Java类中加载so或dll,然后调用声明的native方法。

    第一步:在Java类中声明一个native的方法

    Java代码:TestJni.java

    1. package com.hutest;
    2. public class TestJni {
    3. public native String sayHello(String text); //调用C接口
    4. public static void main(String[] args){
    5. System.loadLibrary("TestJni");
    6. TestJni tj=new TestJni();
    7. String result=tj.sayHello("Hello World!");
    8. System.out.println(result);
    9. }
    10. }

    第二步,使用Javah命令生成包含native方法声明的C头文件

    1、 编译TestJni .java文件

    javac com/hutest/TestJni.java

    2、生成TestJni .h文件(com_hutest_TestJni.h)

    javah com.hutest.TestJni 

    生成的头文件:com_hutest_TestJni.h 

    1. /* DO NOT EDIT THIS FILE - it is machine generated */
    2. #include <jni.h>
    3. /* Header for class com_hutest_TestJni */
    4. #ifndef _Included_com_hutest_TestJni
    5. #define _Included_com_hutest_TestJni
    6. #ifdef __cplusplus
    7. extern "C" {
    8. #endif
    9. /*
    10. * Class: com_hutest_TestJni
    11. * Method: sayHello
    12. * Signature: (Ljava/lang/String;)Ljava/lang/String;
    13. */
    14. JNIEXPORT jstring JNICALL Java_com_hutest_TestJni_sayHello
    15. (JNIEnv *, jobject, jstring);
    16. #ifdef __cplusplus
    17. }
    18. #endif
    19. #endif

    第三步,按照生成的C头文件来写C源文件

    C代码:TestJni.c

    1. /* DO NOT EDIT THIS FILE - it is machine generated */
    2. #include "com_hutest_TestJni.h"
    3. #include "string.h"
    4. JNIEXPORT jstring JNICALL Java_com_hutest_TestJni_sayHello
    5. (JNIEnv *env, jobject obj, jstring string){
    6. return string;
    7. }

    第4步,将C源文件编译成动态连接库(dll/SO)

    这里是在linux环境下,所以是编译成.so文件

    #编译

    $gcc -I /home/cg/java_all/java64/jdk1.8.0_221/include  -I /home/cg/java_all/java64/jdk1.8.0_221/include/linux  TestJni.c -fPIC -shared -o libTestJni.so

    $gcc -I /home/cg/java_all/java64/jdk1.8.0_221/include  -I /home/cg/java_all/java64/jdk1.8.0_221/include/linux  TestJni.c -fPIC -shared -o libTestJni.so

    第五步,把dll/so文件的目录加入PATH环境变量下

    export LD_LIBRARY_PATH=/opt/jnitest:$ LD_LIBRARY_PATH

    第六步,Java类中加载so或dll,然后调用声明的native方法。

    Linux环境下加载so,运行结果如下:

    [root@loaclhost jnitest]# java com.hutest.TestJni

    Hello World!

    备注:其中的一些疑问和回答。

    jni的步骤是先写.java文件定义Nactive方法,然后javac生成class,然后javah生成对应c的头文件,再通过生成的c头文件里定义的函数名写具体实现,然后编译成dll或so

    问:如果是两个人写,那么定义好方法和规范,然后Java开发写好.java的Nactive方法,生成class给和生成c头文件给C开发?

    答:对,先把nactive定义好了把java文件提供一份

    后续新增可以不用提供,复制已经生成好的,改下最后的函数名和参数就行了

    大概了解了,看来想真的弄懂得自己弄个小的demo才行。

    编译和执行

     

     参考:https://www.jb51.net/article/92121.htm

    https://www.jb51.net/article/92121.htm

    https://blog.csdn.net/weixin_33246767/article/details/114254282

    https://www.runoob.com/w3cnote/jni-getting-started-tutorials.html

  • 相关阅读:
    支付宝小程序 头部导航背景颜色渐变
    【C语言趣味教程】(5) 常量:字面常量 | 类型常量 | const 关键字 | const 的声明 | 程序中的只读概念 | const 保护机制 | 如何巧妙区分 “指针常量“ 和 “常量指针“
    排序之快速排序
    SQL Injection 防御——预编译
    华为云云耀云服务器L实例评测 | 搭建docker环境
    13 Pearson检验
    Stream手动分页
    【Pycharm配置】在Pycharm中配置Jupyter环境
    【Golang开发面经】奇安信(两轮技术面)
    k8s 入门到实战--部署应用到 k8s
  • 原文地址:https://blog.csdn.net/fen_fen/article/details/125530507