NDK調用非JNI標準的so文件

博客導航

調用so文件有兩種方式,一種是標準的jni文件,另外一種不是jni標準。jni標準可以直接用jni標準來調用,非jni標準的需要外面包裹一層jni標準才能調用。下面就演示怎麼用。

NKD可以用ndk-build來編譯,也可以用cmake來編譯。這裏用的是cmake。
CMakeList.txt內容。

# 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)

# 這裏設置外部代碼根目錄
set(distribution_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../../distribution)

#調用第三方so文件
add_library(slzr-lib SHARED IMPORTED)
set_target_properties(slzr-lib PROPERTIES IMPORTED_LOCATION
        ${distribution_DIR}/slzr/lib/${ANDROID_ABI}/libslzr.so)

#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
#主so文件配置
add_library(native-lib
        SHARED
        #這裏設置需要引入的c文件
#        ${distribution_DIR}/slzr/src/libposapplication.cpp
        native-lib.cpp)

#這裏設置生成so文件的輸出目錄,可以不設置
set_target_properties(native-lib
        PROPERTIES
        LIBRARY_OUTPUT_DIRECTORY
        "${distribution_DIR}/native-lib/lib/${ANDROID_ABI}")

#這裏設置外部源碼位置
target_include_directories(native-lib PRIVATE
#        ${distribution_DIR}/slzr/src
        ${distribution_DIR}/slzr/include)

find_library(log-lib
        log)


target_link_libraries(native-lib
        slzr-lib   #第三方so文件

        ${log-lib})

CMakeList裏面設置了第三方的so庫地址。
值得注意的是set_target_properties設置需要放到對應的add_library的下面。target_link_libraries需要加入第三方so文件的名稱。
我這裏直接生成一個測試的非標準的jni文件給項目來調用。

這裏是封裝的c++調用。

#include <jni.h>
#include <string>
#include <stdio.h>
#include <iostream>
#include "stdint.h"
#include <libposapplication_global.h>

#include <libposapplication.h>
#include<android/log.h>
#define LOG_TAG "System.out.c"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
/**
 * 封裝c/c++與java的接口
 */


int soso(char *data) {
    printf("*********test*********");
    std::cout << "Hello World!" << std::endl;
    LOGI("這是來自tsoso");
    return 1;
}




extern "C" JNIEXPORT jstring JNICALL
Java_com_example_ndktest2_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello from C++";

    LOGD("調用了testapp");
    testapp();
    LOGI("這是來自so裏面的info信息");

    IC_test cal;
    cal.call_test = soso;
    int i = call_back(&cal);
    LOGI("這是來自so裏面的info123");

    return env->NewStringUTF(hello.c_str());
}

代碼比簡單,testapp();是so文件裏面的函數。call_back是so文件裏面回調函數。這裏設置int soso(char *data)爲回調函數加進去。
下面看下非JNI標準的c代碼。

#include "libposapplication.h"
#include<stdio.h>
#include<iostream>
#include"stdint.h"

LibPosApplication::LibPosApplication()
{
 printf("測試lib");
}
LIBPOSAPPLICATIONSHARED_EXPORT void testapp()
{
     printf("*********test*********");
     std::cout<<"Hello World!"<<std::endl;
    LOGI("這是來自testapp");
}

extern "C"{
LIBPOSAPPLICATIONSHARED_EXPORT int call_back(IC_test *body)
{
    int ret;
    printf("%s\n",__FUNCTION__);
       std::cout<<"Hello call_back!"<<std::endl;
    ret=(body->call_test)("你好啊");
    return 1;
}
}
//回調函數實現

build.gradle裏面設置的並不多,主要是設置一下externalNativeBuild 這個參數值。

android {

    defaultConfig {

        externalNativeBuild {
            cmake {
            }
        }
    }

    externalNativeBuild {
        cmake {
            path "src/main/cpp/CMakeLists.txt"
            version "3.10.2"
        }
    }
}

附件:
demo源碼地址

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章