详解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日

相关文章

  • gdb调试命令的使用及总结

    GDB调试命令的使用及总结 简介 GDB是一个功能强大的调试工具,可以用于调试C程序等各种编程语言。 它可以帮助程序员查找程序崩溃、调查内存问题、跟踪函数调用等问题。 本文旨在提供一些GDB常用调试命令的示例及使用方法,以便于程序员快速定位程序的问题。 命令列表 下面是一些常用的GDB调试命令的列表。 常用命令 命令 描述 run 运行程序 break [f…

    C 2023年5月22日
    00
  • C语言基础知识分享续篇

    C语言基础知识分享续篇 一、数据类型 1.基本数据类型 C语言中基本数据类型有以下5种: 整型(int):用来表示整数。 浮点型(float,double):用来表示小数。 字符型(char):用来表示单个字符。 空类型(void):无返回值的函数的返回类型。 布尔类型(bool):用来表示真或假。 2.数组和指针 数组是一组有序的数据,可以通过下标访问其中…

    C 2023年5月23日
    00
  • C语言内部静态变量与外部静态变量的区别

    当我们定义一个静态变量时,它的存储位置决定了它是内部静态变量还是外部静态变量。 内部静态变量是在函数内部定义的静态变量,它只能在定义它的函数中使用,也就是说,这个静态变量的作用域只在这个函数内部。 外部静态变量是在函数外部定义的静态变量,它可以在整个程序中使用,但是作用域仅限于定义它的文件内部。 总体而言,静态变量都有着不会随时被销毁的特点,程序真正运行的时…

    C 2023年5月10日
    00
  • 盘点2016上半年十大APT神秘黑客组织

    盘点2016上半年十大APT神秘黑客组织 1. 菜鸟组织(Rookie Group) 菜鸟组织是一支来自中国的APT黑客组织,主要针对亚洲国家的政府机构、军队及科技公司进行攻击。他们经常使用钓鱼邮件和恶意附件来传播恶意软件,攻击手法比较简单。因此,这个组织通常会结合大规模攻击,以期望入侵的成功率能相对增加。 示例一:2016年5月,菜鸟组织通过一系列的攻击,…

    C 2023年5月22日
    00
  • JavaScript中的连续赋值问题实例分析

    当我们在 JavaScript 语言中使用连续赋值时,需要注意一些问题。本文将介绍这些问题,并通过实例进行详细分析,帮助开发者更好地理解。 什么是连续赋值? 在 JavaScript 语言中,变量可以连续被赋值。连续赋值是指将多个值赋给多个变量的过程。例如: let a = 1, b = 2, c = 3; a = b = c = 4; console.lo…

    C 2023年5月22日
    00
  • 18核i9-9980XE性能怎么样?英特尔酷睿i9-9980XE处理器详细评测+天梯图

    18核i9-9980XE性能评测 介绍 英特尔酷睿i9-9980XE处理器,拥有18核心和36线程,是英特尔最新一代高端桌面CPU,定位于高端游戏和专业工作。它配备了高主频、高缓存和超线程等先进技术,使其能够在多线程任务和单线程任务方面都能获得出色的性能表现。 本文将对18核i9-9980XE的性能做详细评测,给读者带来全方位的表现和性能数据。 性能测试 1…

    C 2023年5月23日
    00
  • 使用 Visual Studio 2022 开发 Linux C++ 应用程序的过程详解

    标题:使用 Visual Studio 2022 开发 Linux C++ 应用程序的过程详解 简介 Visual Studio 是一个面向开发人员的 IDE,可用于开发各种应用程序,其中就包括了 Linux C++ 应用程序的开发。 本文将详细介绍如何使用 Visual Studio 2022 开发 Linux C++ 应用程序。 步骤 步骤1:配置 Li…

    C 2023年5月23日
    00
  • C++日期和时间编程小结

    C++日期和时间编程小结完整攻略 本文将介绍使用C++编程语言来获取和处理日期和时间的相关技巧和知识。首先,我们需要了解C++标准库中关于日期和时间的头文件<chrono>和<ctime>。 头文件介绍 头文件\ 在C++11标准中,引入了一个新的日期和时间库<chrono>,它提供了丰富的日期和时间操作工具。通过<…

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