Ndk 生成.so(win7)

Android NDK 编译.so 文件指南
本文详细介绍了在Windows 7环境下使用NDK编译生成.so文件的步骤,包括NDK的安装、环境配置、Android Studio项目设置、.mk文件的编写以及使用gradle自动编译的方法。通过这些步骤,开发者可以成功地在自己的Android应用中集成本地C/C++代码。

前提:

1.安装ndk

2.系统的环境配置

在系统的环境变量中添加变量ANDROID_NDK内容为ndk的安装目录,我的是

C:\Users\Administrator\AppData\Local\Android\Sdk\ndk-bundle

之后在path中添加%ANDROID_NDK%;

3、在studio的file->Project Structure中配置ndk的安装路径

这里写图片描述

也可以在local.properties中配置路径

这里写图片描述

4、配置三个常用命令,其它不需要

http://blog.majiajie.me/2016/03/27/%E5%A6%82%E4%BD%95%E4%BC%98%E9%9B%85%E5%9C%B0%E4%BD%BF%E7%94%A8NDK/
参考链接

5、配置gradle.properties

添加
android.useDeprecatedNdk=true

1、.mk编译

1、生成头文件

新建类,写native方法,右击类文件NDK->javah,生成jni目录,目录下有头文件

这里写图片描述

2、在jni下新建一个.cpp文件,进行函数实现

#include "com_tcxy_androidndk_Operator.h"
JNIEXPORT jstring JNICALL Java_com_tcxy_androidndk_Operator_getName(JNIEnv *  env, jobject obj)
{
    return env->NewStringUTF("Hello word !!!");
}

3、写两个.mk文件

这里写图片描述

Android.mk内容为

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := mathwork
LOCAL_SRC_FILES := mathOpeartion.cpp
include $(BUILD_SHARED_LIBRARY)

Application.mk内容为

APP_ABI := all

然后右击jni文件选择NDK->ndk-build,生成libs和obj目录

这里写图片描述

4、修改module的build.gradle

在android{}内部添加

    sourceSets {
        main {
            jni.srcDirs = []   //禁止ndk自动编译
            jniLibs.srcDirs = ['src/main/libs']  //更改jniLibs默认地址
        }
    }

2、ndk自动编译

主要思想就是把.mk的任务交给gradle配置来实现。

先重做前文的1、2步

3、修改module的build.gradle

在defaultConfig {}内部添加

 ndk {
            moduleName "mathwork"          //生成的so名字
            abiFilters "armeabi", "armeabi-v7a", "x86" //输出指定三种abi体系结构下的so库
        }

在android{}内部添加

    sourceSets {
        main {
            jni.srcDirs = ['src/main/jni']    //可直接删除这行,系统默认位置就是src/main/jni
            jniLibs.srcDirs = ['src/main/libs']
        }
    }

make 之后在app\build\intermediates\ndk\debug 中可以找到库文件

Windows 环境下使用 Android NDK 进行交叉编译生成动态库(.so 文件)是完全可行的。Android NDK(Native Development Kit)提供了必要的工具链和库文件,允许开发者在 Windows 上编写、编译和调试 C/C++ 代码,并将其打包为 Android 可使用的动态库。 ### 1. 准备工作 - **安装 Android NDK**:确保已经下载并安装了 Android NDK。可以通过 [Android 官方网站](https://developer.android.com/ndk) 下载最新版本的 NDK。安装后,建议将 NDK 的路径添加到系统环境变量中,以便命令行工具可以访问。 - **安装构建工具**:NDK 提供了 `ndk-build` 脚本,它是基于 GNU Make 的封装,用于简化构建过程。此外,也可以使用 CMake 或手动调用 `clang` 进行交叉编译。 - **了解目标架构**:Android 支持多种 CPU 架构,如 `armeabi-v7a`、`arm64-v8a`、`x86_64` 等。需要根据目标设备选择合适的架构。 ### 2. 使用 `ndk-build` 构建动态库 创建一个包含以下文件结构的项目: ``` MyJNILib/ ├── Android.mk ├── Application.mk ├── jni/ │ └── native-lib.cpp └── libs/ ``` #### `Android.mk` ```makefile LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := native-lib LOCAL_SRC_FILES := native-lib.cpp include $(BUILD_SHARED_LIBRARY) ``` #### `Application.mk` ```makefile APP_ABI := armeabi-v7a arm64-v8a x86_64 APP_PLATFORM := android-21 ``` 在这个例子中,`APP_ABI` 指定了要构建的目标架构,`APP_PLATFORM` 指定了最低 API 级别。 #### `native-lib.cpp` ```cpp #include <jni.h> #include <string> extern "C" JNIEXPORT jstring JNICALL Java_com_example_myapp_MainActivity_stringFromJNI( JNIEnv* env, jobject /* this */) { std::string hello = "Hello from C++"; return env->NewStringUTF(hello.c_str()); } ``` 然后在命令行中进入 `jni` 目录并执行: ```bash ndk-build ``` 构建完成后,`libs/` 目录下将生成对应架构的 `.so` 文件。 ### 3. 使用 CMake 构建动态库 如果项目结构更复杂或需要更灵活的配置,可以使用 CMake。首先确保在 Android Studio 中启用了 CMake 支持。 #### `CMakeLists.txt` ```cmake cmake_minimum_required(VERSION 3.10.2) project("native-lib") add_library( # Sets the name of the library. native-lib # Sets the library as a shared library. SHARED # Provides a relative path to your source file(s). src/main/cpp/native-lib.cpp ) find_library( # Sets the name of the path variable. log-lib # Specifies the name of the NDK library that # you want CMake to locate. log ) target_link_libraries( # Specifies the target library. native-lib # Links the target library to the log library # included in the NDK. ${log-lib} ) ``` 在 `build.gradle` 中配置 CMake: ```gradle android { ... defaultConfig { ... externalNativeBuild { cmake { cppFlags "" } } } externalNativeBuild { cmake { path "CMakeLists.txt" version "3.10.2" } } } ``` 执行 `./gradlew build` 即可生成动态库。 ### 4. 手动调用 Clang 进行交叉编译 如果希望更精细地控制编译过程,可以直接使用 NDK 提供的 `clang` 工具链进行交叉编译。例如: ```bash $NDK_HOME/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android21-clang++ \ -shared -fPIC native-lib.cpp \ -o libnative-lib.so ``` 其中 `$NDK_HOME` 是 NDK 的安装路径,`aarch64-linux-android21-clang++` 是针对 `arm64-v8a` 架构的编译器,`-shared` 表示生成共享库,`-fPIC` 表示生成位置无关代码。 ### 5. 集成到 Android 应用中 生成的 `.so` 文件应放置在 `src/main/jniLibs/` 目录下,按照架构分类存放。例如: ``` app/ └── src/ └── main/ └── jniLibs/ ├── arm64-v8a/ │ └── libnative-lib.so ├── armeabi-v7a/ │ └── libnative-lib.so └── x86_64/ └── libnative-lib.so ``` 在 Java/Kotlin 代码中加载库并调用 JNI 方法: ```java public class MainActivity extends AppCompatActivity { static { System.loadLibrary("native-lib"); } public native String stringFromJNI(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView tv = findViewById(R.id.sample_text); tv.setText(stringFromJNI()); } } ``` ### 6. 调试与优化 - **日志输出**:可以在 C++ 代码中使用 `<android/log.h>` 提供的 `__android_log_print` 函数输出日志。 - **性能优化**:根据目标架构选择合适的编译选项,如 `-O3` 进行优化。 - **内存管理**:注意 JNI 中的本地引用管理,避免内存泄漏。 通过上述方法,可以在 Windows 环境下使用 Android NDK 成功交叉编译生成动态库,并将其集成到 Android 应用中[^1]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值