JNI

作者: lipyhui | 来源:发表于2018-11-23 07:32 被阅读0次

    一、说明

      笔记主要是记录一些本人在开发当中的学习和使用笔记。笔记内容包含一些本人觉得重要的知识点、本人易犯的错误等。
      由于本人水平有限,其中出现的错误或者不合理的地方望各位读者多多包含,并指出其中不合理和错误的地方,以便我来修正。谢谢!

    二、笔记时间

      2018年10月17日

    三、简述

      本文主要讲述Android APP JNI的简单使用方式。

    四、详情

    1、简介

      JNI的全称是Java Native Interface,它用来实现Java与其他语言的通信(主要是C和C++)。
      本文是使用Android studio + CMake来进行JNI开发的,因此需要安装Android Studio、NDK、CMake。

    2、详情

      Java里调用C语言函数需要先调用“System.loadLibrary("XXX")”,其中XXX是C语言编译的库文件名;以下代码中定义native的方法在C文件中实现的同时也供Java进行调用。以通俗的话说这个native方法是Java和C语言沟通的桥梁。
      Java方法名和C函数名关系:C函数名=Java_文件路径_文件名_Java方法名,文件路径用"_"隔开。这样我们就可以在Java里调用C语言中的函数,同时我们也可以通过反射的方式在C语言函数中调用Java方法调用。

    //Java方法
    package com.lipy.demo.uart;
    public class UartJNI {
        static {
            System.loadLibrary("uart");
        }
    
        /**
         * 串口初始化
         *
         * @param namePath 串口路径
         * @return    串口文件描述符
         */
        public static native int initUart(String namePath);
    }
    
    
    //C函数
    PORT jint JNICALL
    Java_com_lipy_demo_uart_UartJNI_initUart(JNIEnv *env, jobject obj, jstring namePath) {
        return init_uart_port((*env)->GetStringUTFChars(env, namePath, 0));
    }
    

      注:

    1)Java与native数据类型映射: Java与native数据类型映射

    2)采用CMake编译C文件,需要我们在“CMakeLists.txt”中配置编译生成lib名和编译C文件等。如下代码所示。

    # For more information about using CMake with Android Studio, read the
    # documentation: https://d.android.com/studio/projects/add-native-code.html
    
    # Sets the minimum version of CMake required to build the native library.
    
    cmake_minimum_required(VERSION 3.4.1)
    
    # Creates and names a library, sets it as either STATIC
    # or SHARED, and provides the relative paths to its source code.
    # You can define multiple libraries, and CMake builds them for you.
    # Gradle automatically packages shared libraries with your APK.
    
    add_library( # Sets the name of the library.
                 uart
    
                 # Sets the library as a shared library.
                 SHARED
    
                 # Provides a relative path to your source file(s).
                 src/main/cpp/uart.c)
    
    # Searches for a specified prebuilt library and stores the path as a
    # variable. Because CMake includes system libraries in the search path by
    # default, you only need to specify the name of the public NDK library
    # you want to add. CMake verifies that the library exists before
    # completing its build.
    
    find_library( # Sets the name of the path variable.
                  log-lib
    
                  # Specifies the name of the NDK library that
                  # you want CMake to locate.
                  log )
    
    # Specifies libraries CMake should link to your target library. You
    # can link multiple libraries, such as libraries you define in this
    # build script, prebuilt third-party libraries, or system libraries.
    
    target_link_libraries( # Specifies the target library.
                           uart
    
                           # Links the target library to the log library
                           # included in the NDK.
                           ${log-lib} )
    

    3)当在C中使用Java对象(例如:String等)后,一定需要释放转换资源,不然容易造成内存溢出;以下代码中就需要释放Java传入的参数jbyteArray和转换数据jbyte指针。

    //C函数
    JNIEXPORT jint JNICALL
    Java_com_lipy_demo_uart_UartJNI_sendUartData(JNIEnv *env, jobject obj, jstring namePath, jint fd, jbyteArray datas,
                                                      jint length, jlong timeout_ms) {
        unsigned char *sendBuff = NULL;
        jbyte *ba = (*env)->GetByteArrayElements(env, datas, JNI_FALSE); //jbyteArray转为jbyte*
    
        if (length > 0) {
            sendBuff = (char *) malloc(length + 1);         //预留"\0"
            memcpy(sendBuff, ba, length);
            sendBuff[length] = '\0';
        }
        (*env)->ReleaseByteArrayElements(env, datas, ba, 0);  //释放掉资源
    
        return uart_send_data((*env)->GetStringUTFChars(env, namePath, 0), fd, sendBuff, length, timeout_ms);
    }
    

    3、示例源码

      示例源码:https://github.com/lipyhui/android_app_demo/tree/master/UART

    相关文章

      网友评论

        本文标题:JNI

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