Android Studio中使用自建so动态链接库

222 阅读2分钟

Android Studio中使用自建动态链接库

2024-11-8
在第一次构建和每次添加新内容和时候都运行一次,方便定位问题

目录

  • 构建so库
  • 创建android native-cpp模版项目
  • 添加so、h文件
  • 修改cmake文件
  • 使用so库

构建so库

so库源码

  • foo.cc

    #include "foo.h"
    
    int add(int a, int b) {
        return a + b;
    }
    
  • foo.h

    #ifndef FOO_H
    #define FOO_H
    
    int add(int,int);
    
    #endif
    

构建动态链接库

我这里使用xmake,类似于cmake

  • xmake.lua

    add_rules("mode.debug", "mode.release")
    
    target("foo")
        set_kind("shared")
        add_files("src/foo.cpp")
    
    target("demo_cppLib")
        set_kind("binary")
        add_deps("foo")
        add_files("src/main.cpp")
    
  • 构建后的文件结构

    android
    ├── arm64-v8a
    │   └── release
    │       ├── demo_cppLib
    │       └── libfoo.so
    ├── armeabi-v7a
    │   └── release
    │       ├── demo_cppLib
    │       └── libfoo.so
    ├── x86
    │   └── release
    │       ├── demo_cppLib
    │       └── libfoo.so
    └── x86_64
        └── release
            ├── demo_cppLib
            └── libfoo.so
    

创建android native-cpp模版项目

  • 选择 Native C++

    82251516-0a42-432b-856b-edd43c1eb826.png

  • [可选] 将config language改为Groovy DSL

    a32a14aa-7971-4f64-9866-a793e53e6f73.png

添加so、h文件

  • 将左上角项目文件结构改为Project,在main目录新建jniLibs文件夹,main/cpp目录下添加include文件夹

    %E6%88%AA%E5%B1%8F2024-11-08_15.30.41.png

  • 按照架构将so文件添加到子文件夹下

    app/src/main/jniLibs
    ├── arm64-v8a
    │   └── libfoo.so
    ├── armeabi-v7a
    │   └── libfoo.so
    ├── x86
    │   └── libfoo.so
    └── x86_64
        └── libfoo.so
    
    
  • 添加头文件

    app/src/main/cpp
    ├── CMakeLists.txt
    ├── include
    │   └── foo.h
    └── native-lib.cpp
    
    

修改cmake文件内容

原内容

cmake_minimum_required(VERSION 3.22.1)

project("demo")

add_library(${CMAKE_PROJECT_NAME} SHARED
        native-lib.cpp)

target_link_libraries(${CMAKE_PROJECT_NAME}
        android
        log)
  • 直接在 target_link_libraries 下添加链接so文件

    target_link_libraries(${CMAKE_PROJECT_NAME}
            android
            log
            ${CMAKE_SOURCE_DIR}/../jniLibs/${CMAKE_ANDROID_ARCH_ABI}/libfoo.so
            )
    
  • 添加头文件

    include_directories(${CMAKE_SOURCE_DIR}/include)

  • 完整内容

    cmake_minimum_required(VERSION 3.22.1)
    
    project("demo")
    
    include_directories(${CMAKE_SOURCE_DIR}/include)
    
    add_library(${CMAKE_PROJECT_NAME} SHARED
            native-lib.cpp)
    
    target_link_libraries(${CMAKE_PROJECT_NAME}
            android
            log
            ${CMAKE_SOURCE_DIR}/../jniLibs/${CMAKE_ANDROID_ARCH_ABI}/libfoo.so
    )
    

重新构建项目

Build -> Rebuild Project

Build -> Refresh Linked C++ Projects

%E6%88%AA%E5%B1%8F2024-11-08_15.14.39.png %E6%88%AA%E5%B1%8F2024-11-08_15.22.08.png

使用so库

  • native-lib.cpp源文件

    #include <jni.h>
    #include <string>
    
    extern "C" JNIEXPORT jstring JNICALL
    Java_com_example_demo_MainActivity_stringFromJNI(
            JNIEnv* env,
            jobject /* this */) {
        std::string hello = "Hello from C++";
        return env->NewStringUTF(hello.c_str());
    }
    
  • 修改后

    #include <jni.h>
    #include <string>
    
    #include "foo.h"
    
    extern "C" JNIEXPORT jstring JNICALL
    Java_com_example_demo_MainActivity_stringFromJNI(
            JNIEnv* env,
            jobject /* this */) {
        std::string hello = "Hello from C++";
        int num = add(1,1);
        std::string str = std::to_string(num);
        
        return env->NewStringUTF(str.c_str());
    }
    

成功显示函数返回内容

%E6%88%AA%E5%B1%8F2024-11-08_15.23.55.png