详解Android studio ndk配置cmake开发native C

下面是详解Android Studio NDK配置CMake开发Native C的完整攻略。

一、前置条件

在进行此项操作前,先确保以下环境已准备好:

  1. Android Studio
  2. NDK(可以在 Android Studio 中下载)
  3. CMake

二、配置 CMake

CMake 是一个开源程序,它可以管理代码的编译过程。在 Android Studio 中使用 CMake 可以轻松配置 C/C++ 代码的编译过程。我们需要先配置 CMake,从而实现使用 CMake 开发 Native 代码。

(一)在 Android Studio 中配置 CMake

  1. 打开 Android Studio。
  2. 打开您的 Android 项目。
  3. 如果还没有,可以添加一个 cpp 文件。右键点击您的项目的 app/src/main 目录 ,选择 New > C++/JNI > C++ File。
  4. 在C++文件中输入一些代码,以便 Cmake 和 NDK 可以查看配置情况。例如:

```c++
#include
#include
#include

#define LOG_TAG "HelloWorld"
#define LOGI(...) android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS)

extern "C" JNIEXPORT jstring JNICALL
Java_com_example_hellojni_MainActivity_stringFromJNI(JNIEnv env,
jobject /
this */) {
std::string hello = "Hello from C++";
LOGI("I am the hello-jni-javatest!");
return env->NewStringUTF(hello.c_str());
}
```

这是一个简单的 hello world 的 C++ 文件,它可以把字符串传递给调用该函数的 Java 代码。

  1. 打开 CMakeLists.txt 文件,它在您的项目的 /app/CMakeLists.txt 目录下。该文件控制 CMake 的配置过程。在文件中输入以下代码:

```
cmake_minimum_required(VERSION 3.4.1)

# set up shared library
add_library(hello-jni SHARED
hello-jni.cpp)

find_library(log-lib log)

# linking shared library to log library
target_link_libraries(hello-jni ${log-lib})
```

此代码片段告诉 CMake 创建一个名为“hello-jni”的共享库,并将其与 hello-jni.cpp 源代码链接。此文件还告诉 CMake 链接该库与 Android 的 log 库。

(二)在 Android Studio 中生成应用程序

  1. 选择 Build > Make Project,Android Studio 将使用 CMake 编译您的项目。
  2. 使用 Build > Rebuild Project 将重新生成项目,以确保更改已应用。

三、配置 和 实现 NDK

在了解了如何配置 CMake 之后,我们现在可以继续设置 NDK 来生成本机代码。此操作需要打开项目中的 build.gradle 文件。

  1. 在应用程序级别的 build.gradle 文件中添加以下块。此块指定您要使用的 CMake 版本并告诉 Android Studio 您是否要构建本机代码:

externalNativeBuild {
cmake {
version "3.10.2"
path "CMakeLists.txt"
}
}

  1. 接下来,添加以下两个 NDK 环境变量以应用程序级别的 build.gradle 文件中:

```
android {
...
defaultConfig {
...
externalNativeBuild {
cmake {
cppFlags "-fexceptions"
}
}
}

 //配合之前添加的CMake块以使用CMake构建并传递信息
 externalNativeBuild {
    cmake {
        version "3.10.2"
        path "CMakeLists.txt"
    }
 }

 //添加NDK路径,注意替换为自己的NDK路径
 ndk {
    platformVersion 27
    abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86','x86_64'
    defualtConfig.ndk {
        abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86','x86_64'
    }
    //注意替换为自己的NDK路径
    path "C:\\Users\\Administrator\\AppData\\Local\\Android\\Sdk\\ndk-bundle"
}

}
```

  1. 现在,使用以下语句将您的 hello-jni 应用程序从 Java 调用你设置的本机语言 C++ 文件:

String outputString = null;
// /data/data/[package]/lib
File libraryFile = context.getDir("lib", Context.MODE_PRIVATE);
System.loadLibrary("hello-jni");
HelloJni helloJni = new HelloJni();
outputString = helloJni.stringFromJNI();

到这里,配置 CMake 和 NDK 的过程就已经完成了。接下来,让我们通过两个示例来更好地理解。

四、示例说明

示例1:整数加法运算

1.添加 native 方法:

需在你的 MainActivity.java 文件中,添加通过 native 关键字定义的 add 方法,该方法接受两个整数参数并返回它们的和。

package com.example.ndkespresso;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    static {
        System.loadLibrary("native-lib");
    }

    private native int add(int a, int b);

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

        int x = 4;
        int y = 6;

        int sum = add(x, y);
        Log.d(TAG, "Sum of " + x + " and " + y + " is: " + sum);
    }
}

2.添加本机代码 CPP:

接下来,我们需要实现 add 方法的本机代码。在您的 Android 项目中,在您的 cpp 文件中添加以下代码片段:

extern "C"
JNIEXPORT jint JNICALL
Java_com_example_ndkespresso_MainActivity_add(JNIEnv *env, jobject object, jint a, jint b) {

    return a+b;

}

现在,编译和运行应用,你将在控制台中看到你添加的日志打印出合计值。

示例2:基本算法-冒泡排序算法

1.添加 native 方法:

需在你的 MainActivity.java 中添加通过 native 关键字定义的 sort 方法。该方法将接受一个 int 数组和 int 数组的长度作为参数,并按升序对数组进行排序。

   package com.example.ndkespresso;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;

import java.util.Arrays;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    static {
        System.loadLibrary("native-lib");
    }

    private native int[] sort(int[] unsorted, int length);

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

        int arr[] = {1, 60, 90, 77, 99, 1, 200, 400};

        Log.d(TAG, "Initial Array : " + Arrays.toString(arr));

        int sortedArr[] = sort(arr, arr.length);

        Log.d(TAG, "Sorted Array : " + Arrays.toString(sortedArr));
    }
}

2.添加本机代码 CPP:

接下来,添加本机代码以对传递的整数数组进行排序。您可以使用 c++ 冒泡排序来实现此目的。

在您的 Android 项目中,在您的 cpp 文件中添加以下代码片段:

#include <jni.h>
#include <string>
#include <algorithm>
#include <vector>

extern "C"
JNIEXPORT jintArray JNICALL
Java_com_example_ndkespresso_MainActivity_sort(JNIEnv *env, jobject thiz, jintArray unsorted,
                                                jint length) {
    std::vector<int> vec;

    jint *array = env->GetIntArrayElements(unsorted, nullptr);
    if (array) {
        for (int i = 0; i < length; i++) {
            vec.push_back(array[i]);
        }
    }
    env->ReleaseIntArrayElements(unsorted, array, JNI_ABORT);

    // sorted vector using standard library
    std::sort(vec.begin(), vec.end());

    jintArray result = env->NewIntArray(length);
    if (result == nullptr) {
        return nullptr; /* out of memory error thrown */
    }

    jint *nativeArray = env->GetIntArrayElements(result, nullptr);
    if (nativeArray == nullptr) {
        return nullptr; /* out of memory error thrown */
    }

    // copy vector to native array
    for (int i = 0, n = vec.size(); i < n; i++) {
        nativeArray[i] = vec[i];
    }

    env->ReleaseIntArrayElements(result, nativeArray, 0); // release 'resultArray'
    return result; // return the jni array
}

现在,编译和运行应用程序,您将在控制台中看到您打印的排序数组。

到这里,我们就成功地完成了 Android Studio NDK配置CMake开发native C的完整攻略,希望能对您有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解Android studio ndk配置cmake开发native C - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • mysql(5.6及以下)解析json的方法实例详解

    mysql(5.6及以下)解析json的方法实例详解 背景 在以往的开发中,我们通常使用MySQL来存储数据,然而在数据中存在着大量的json类型的数据,如何快速、便捷的解析json数据就变得尤为重要。本文将介绍Mysql(5.6及以下)中解析json类型数据的方法及实例。 操作步骤 使用JSON_EXTRACT()方法解析json数据 JSON_EXTRA…

    C 2023年5月23日
    00
  • 在C++中反射调用.NET的方法(二)

    在C++中反射调用.NET的方法的攻略可以分为以下几个步骤: 1. 首先需要准备好以下环境 Visual Studio 开发环境(如版本为VS 2019) C++/CLI Windows窗体应用程序,或其他CLI类型项目 .NET Framework SDK(如版本为.NET Framework 4.7.2) 被调用的.NET程序集(如例子中的DLL文件) …

    C 2023年5月22日
    00
  • C#实现Json转DataTable并导出Excel的方法示例

    我将为你详细讲解“C#实现Json转DataTable并导出Excel的方法示例”的完整攻略。以下是该攻略的步骤及示例说明: 步骤一:将Json转为DataTable 使用C#实现Json转DataTable的方法有很多种,比如使用JSON.NET库等。我们以JSON.NET库为例,具体步骤如下: 引用Newtonsoft.Json库: 在Visual St…

    C 2023年5月23日
    00
  • 基于C++编写一个Json解析器

    下面是基于C++编写一个Json解析器的完整攻略: 确定解析策略 在开始编写Json解析器之前,我们需要先考虑解析策略。Json由一系列键值对组成,每个键值对由一个键和一个值组成。值可以是字符串、数值、布尔值、数组、对象等形式。因此,我们可以采用自顶向下的递归下降解析器作为解析策略。即先解析出Json对象,再逐步递归地解析出内部的数组或对象。 编写代码 定义…

    C 2023年5月23日
    00
  • angular指令笔记ng-options的使用方法

    下面我将详细讲解“angular指令笔记ng-options的使用方法”的完整攻略。首先,让我们来看一下ng-options的作用是什么。 什么是ng-options ng-options是AngularJS中的一条指令,它用于创建选项列表。在使用这个指令时,我们可以简单地通过设置相关的属性来定义可选项。ng-options指令通常与ng-model指令一起…

    C 2023年5月22日
    00
  • 到底如何呢?富士康Ligtning&USB-C数据线测评

    制定测试方案 在进行富士康Ligtning&USB-C数据线的测评之前,需要制定测试方案。主要需要测试以下几点: 兼容性 传输速度 做工质量 安全性能 兼容性测试 取一个iOS设备,如iPhone,连接富士康Ligtning&USB-C数据线,测试手机是否能够正常充电和传输数据。同样的,取一个安卓设备连接USB-C接口进行测试,检查是否能正常…

    C 2023年5月23日
    00
  • C++ win系统如何用MinGW编译Boost库

    C++ Win系统如何用MinGW编译Boost库 Boost库是一个开源的、高质量的库,包括许多各种各样的工具和库,被广泛应用于C++编程中。MinGW是一个基于GNU编译器的Windows程序开发工具包,提供了一个完整的开发环境,可用于开发Windows应用程序。本攻略介绍如何使用MinGW编译Boost库。 准备工作 1.下载和安装MinGW可以从Mi…

    C 2023年5月23日
    00
  • C/C++中for语句循环用法以及练习举例

    下面是对C/C++中for语句循环用法以及练习举例的详细讲解。 1. for循环语法 for循环是一种常用的循环结构,它的语法如下: for (初始化表达式; 循环条件; 更新表达式) { 循环体 } 其中,初始化表达式一般是用来初始化循环控制变量的,循环条件是一个判断式,根据该式的返回值判断是否进入循环,更新表达式则在每次迭代之后更新循环控制变量的值。循环…

    C 2023年5月22日
    00
合作推广
合作推广
分享本页
返回顶部