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++
-
[可选] 将config language改为Groovy DSL
添加so、h文件
-
将左上角项目文件结构改为Project,在main目录新建jniLibs文件夹,main/cpp目录下添加include文件夹
-
按照架构将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
使用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()); }
成功显示函数返回内容