NDK16_NDK编译生成so并CMAKE集成

NDK开发汇总

一 Linux环境生成so文件

1 新建源文件

vim main.c

内容

int test(){
 return 11;
}
~  

2 编译

参考: NDK16_Linux中使用NDK编译安卓可用的.c

  1. 配置gcc临时环境变量
export CC=android-ndk-r17c/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc
  1. 配置头文件临时环境变量
export AAA="--sysroot=/home/bao/android-ndk-r17c/platforms/android-21/arch-arm -isystem /home/bao/android-ndk-r17c/sysroot/usr/include -isystem /home/bao/android-ndk-r17c/sysroot/usr/include/arm-linux-androideabi"

  1. 生成so
$CC $AAA -fPIC -shared main.c -o libTest.so
  • -shared 生成动态库
  • -static 生成静态库

查看so中方法:
(so拷贝到aarch64-linux-android-nm同路径下)

/home/bao/android-ndk-r17c/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-nm libTest.so 

NDK16_NDK编译生成so并CMAKE集成_第1张图片

二 CMAKE集成

  1. AS新建一个新的Android项目include C++ support

  2. Project视图下,项目main文件夹下创建文件路径
    jniLibs/armeabi-v7a

  3. 将Linux环境生成的libTest.so添加到上述目录
    NDK16_NDK编译生成so并CMAKE集成_第2张图片

  4. 项目自带的native-lib.cpp中调用libTest.so中方法
    注意:extern “C”,引入了android/log.h打印调用结果

#include 
#include 
#include 
extern "C" {
    extern int test();
};
extern "C" JNIEXPORT jstring

JNICALL
Java_com_example_ray_ndk16_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    __android_log_print(ANDROID_LOG_ERROR,"jni","libTest.so 里面的test方法:%d",test());
    return env->NewStringUTF(hello.c_str());
}

  1. 配置CMakeLists.txt
  • 指定so库路径
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} L${CMAKE_SOURCE_DIR}/src/main/jniLibs/armeabi-v7a")
  • 链接库

target_link_libraries 添加Test,省略lib和.so (libTest.so →Test)

# 设置一个变量
# CMAKE_CXX_FLAGS C++的参数 会传给编译器
# CMAKE_C_FLAGS C的参数 会传给编译器
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/src/main/jniLibs/armeabi-v7a")

# 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.
                       native-lib
                        Test
                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )

也可以这样配置

add_library(Test SHARED IMPORTED)
set_target_properties(Test PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/armeabi-v7a/libTest.so)

  1. 配置build.gradle 设置支持手机平台: abiFilters “armeabi-v7a”
 defaultConfig {
        applicationId "com.example.ray.ndk16"
        minSdkVersion 17
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                cppFlags "-frtti -fexceptions"
                abiFilters "armeabi-v7a"
            }
        }
    }
  1. java中加载库:System.loadLibrary(“Test”);
public class MainActivity extends AppCompatActivity {

    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
        System.loadLibrary("Test");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Example of a call to a native method
        TextView tv = (TextView) findViewById(R.id.sample_text);
        tv.setText(stringFromJNI());
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();
}

  1. 运行结果
    NDK16_NDK编译生成so并CMAKE集成_第3张图片

你可能感兴趣的:(NDK)