android studio 3.2 cmake jni调用第三方库动态库

jni的基本使用方法请看我的另外一篇博客

https://blog.csdn.net/qq_34759481/article/details/83825826https://mp.csdn.net/postedit/83825826

 

总体思路:

  1. 新建一个my.cpp和my.h文件
  2. 利用android studio中的cmake工具将my.cpp编译成全架构(armeabi-v7a,arm64-v8a,x86,x86_64)的库文件。编译时很多问题,报错时出现x86或者armeabi都是因为没有对应的架构造成的,我们索性就直接造一个全架构的库。
  3. 将第2步中生成的库链接到native-lib.so(系统自动生成的库)中
  4. 运行,看在native-lib.cpp中的函数能否调用my.cpp中的函数

我们从头开始,最好新建立一个文件。

1.建立jni文件

不多说,看https://blog.csdn.net/qq_34759481/article/details/83825826https://mp.csdn.net/postedit/83825826

建立好之后先运行app,看能否运行,不能运行就先百度解决,正常运行之后再进行后面的操作


2.新建my.cpp和my.h

1.在Project视图下 app/src/main/cpp 目录下创建my.cpp同时创建头文件my.h

android studio 3.2 cmake jni调用第三方库动态库_第1张图片

2.在my.cpp写一个函数,并且添加android的日志库,以便知道当前函数是否被正确被调用

my.h如下:

#ifndef JNITEST2_MY_H
#define JNITEST2_MY_H


//-----------------------------横线里面的内容为新增--------------------------
#include 
#define  LOG    "JNILOG"
#define  LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG,LOG,__VA_ARGS__)
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG,__VA_ARGS__)
#define  LOGW(...)  __android_log_print(ANDROID_LOG_WARN,LOG,__VA_ARGS__)
#define LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG,__VA_ARGS__)
#define LOGF(...)  __android_log_print(ANDROID_LOG_FATAL,LOG,__VA_ARGS__)

int my_fun();
//-------------------------------------------------------------------------

#endif //JNITEST2_MY_H

my.cpp

#include "my.h"

//-----------------------------横线里面的内容为新增--------------------------
int my_fun()
{
    LOGD("android studio jni");
    return 111;
}
//-------------------------------------------------------------------------

3.将my.cpp编译成全架构的.so库

1.修改CMakeLists.txt,只新增了两句,原来的不需要改

cmake_minimum_required(VERSION 3.4.1)

add_library(native-lib SHARED src/main/cpp/native-lib.cpp)

#-----新增--------
add_library(my-lib SHARED src/main/cpp/my.cpp)

find_library(log-lib log)

target_link_libraries(native-lib ${log-lib})

#-----新增---------------
target_link_libraries(my-lib ${log-lib})

2.修改app级别下的build.gradle新增一句

android studio 3.2 cmake jni调用第三方库动态库_第2张图片

3.点击make project

android studio 3.2 cmake jni调用第三方库动态库_第3张图片

4.编译成功之后,查看生成的库

    在Project目录下   app/build/intermediates/cmake/debug/obj/各种架构

    libmy-lib.so就是我们需要链接到libnative-lib.so的库

android studio 3.2 cmake jni调用第三方库动态库_第4张图片

4.将libmy-lib.so链接到native-lib.so

1.修改CMakeLists.txt文件

cmake_minimum_required(VERSION 3.4.1)

add_library(native-lib SHARED src/main/cpp/native-lib.cpp)

#-----删除--------
#add_library(my-lib SHARED src/main/cpp/my.cpp)

#-----新增---------
add_library(apple SHARED IMPORTED)
#-----新增---------
set_target_properties(apple PROPERTIES IMPORTED_LOCATION
        ${CMAKE_CURRENT_SOURCE_DIR}/build/intermediates/cmake/debug/obj/${CMAKE_ANDROID_ARCH_ABI}/libmy-lib.so
        )

find_library(log-lib log)

#------修改---------
target_link_libraries(native-lib apple ${log-lib})

#-----删除---------------
#target_link_libraries(my-lib ${log-lib})

#删除的就表示不要了,#新增就表示新添加的,#修改就表示在原来的基础上修改

说明一下set_target_properties这里面的参数。

${CMAKE_CURRENT_SOURCE_DIR} 表示app这个文件夹,也可以用别的参数来表示。因为Android studio的版本不同,参数可能回不一样,但是一定要能定位到cmake/debug/obj这个文件夹。可以用ctrl+左键来试一下能否被识别。

${CMAKE_ANDROID_ARCH_ABI}表示系统会根据自己的要求去不同的架构目录下去寻找libmy-lib.so,所以不要指定单独的文件夹

2.在native-lib.cpp中调用我们my.cpp的函数

#include 
#include 

//---------新增
#include "my.h"

extern "C" JNIEXPORT jstring JNICALL
Java_com_example_tuweiguang_jnitest2_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    
//-----------新增-------------
    int x = 0;
    x = my_fun();
    LOGD("x = %s",x);
//---------------------------
    
    return env->NewStringUTF(hello.c_str());
}

5.运行app

点击运行app

android studio 3.2 cmake jni调用第三方库动态库_第5张图片

成功调用


至此,jni调用第三方库的教程结束。

还有一些其他问题,目前本人也正在学习,希望共勉:

1.如果我们手里只有单一架构的库,任然希望就在这种架构的及其上运行这种单一架构的库

2.如果你有任何问题,也可以留言,一起讨论

你可能感兴趣的:(Java)