当前位置: 首页 > news >正文

HarmonyOS NEXT系列之编译三方C/C++库

编译三方C/C++库

  • 〇、前言
  • 一、新建 C/C++ 项目
    • 1、目录设置
    • 2、更新 CMakeLists.txt
    • 3、编写C/C++ 方法
  • 二、编译库文件
  • 三、使用预编译库
    • 1、引入头文件
    • 2、引入库文件
    • 3、在 NAPI 中使用 simpleReturnString 方法
      • 3.1、新增NAPI
      • 3.2、使用 NAPI

〇、前言

熟悉主流编程语言的开发者,相比心里对 C/C++ 语言的非跨平台性,早已有所深刻体会。虽然,C/C++ 代码无法像 Python 或 Java 那样一次编写到处运行,但却允许进行制品定制:即为目标平台量身定做输出相应的制品

而 HarmonyOS NEXT 系统,就是 C/C++ 代码编译的目标平台中的一种,而 HarmonyOS NEXT 项目中,使用 C/C++ 代码的方式,一种是直接在 NDK 模块中编写相应的 C/C++ 代码,另一种则是以 NDK 模块为桥梁将三方库集成到项目中;而在第二种方式中,必须先有一个能够在 HarmonyOS NEXT 平台上进行运行的库文件:xxxx.so

而本篇正是要向大家普及如何将一个三方 C/C++ 库编译成 HarmonyOS NEXT 平台中能够直接使用的方法库。

一、新建 C/C++ 项目

这里推荐从零开始进行体验,也即是由自己一手创建一个新的 C/C++ 项目,为了方便源代码进行编译,需要使用 CMake 工具作为项目管理工具。

1、目录设置

使用 CMake 管理项目的 C/C++ 项目,在项目根目录中都会创建一个 CMakeLists.txt 文件,我们以该文件为参照,在同级目录中新建src目录和include目录,最终的项目目录结构如下:

project-root:- src/- include/- CMakeLists.txt

2、更新 CMakeLists.txt

对于新增的目录,默认情况下,都不会被 CMake 所识别到,需要通过 CMakeLists 文件去引入,比如,在上面的目录结构中,想要 include 目录下的所有头文件、以及src目录下的所有源文件,都能在当前项目中使用,就需要在 CMakeLists 中添加如下内容:

file(GLOB_RECURSE SOURCES "src/*.cpp")
include_directories(include)
add_library(${PROJECT_NAME} SHARED library.cpp${SOURCES}
)

另外,为了规范制品输出目录,不妨在 CMakeLists 文件末尾加上这样一段代码:

# 输出设置
set_target_properties(${PROJECT_NAME} PROPERTIESLIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/libs/${OHOS_ARCH}OUTPUT_NAME "${PROJECT_NAME}"SUFFIX ".so"
)

OHOS_ARCH 指代目标平台的芯片架构,以 HarmonyOS NEXT 来说,就是arm64-v8a,最终,完整的 CMakeLists 文件如下:

cmake_minimum_required(VERSION 3.27)
project(HMOSThirdLib)set(CMAKE_CXX_STANDARD 17)
# 工具链和平台配置
set(CMAKE_TOOLCHAIN_FILE"/Applications/DevEco-Studio.app/Contents/sdk/default/openharmony/native/build/cmake/ohos.toolchain.cmake"CACHE STRING "" FORCE)set(CMAKE_INSTALL_PREFIX "/output/HMOSThirdLib" CACHE PATH "" FORCE)
set(OHOS_ARCH "arm64-v8a" CACHE STRING "" FORCE)
# 标准配置(需放在工具链设置之后)
enable_language(C CXX)
file(GLOB_RECURSE SOURCES "src/*.cpp")
include_directories(include)
add_library(HMOSThirdLib SHARED library.cpp${SOURCES}
)
# 输出设置
set_target_properties(HMOSThirdLib PROPERTIESLIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/libs/${OHOS_ARCH}OUTPUT_NAME "HMOSThirdLib"SUFFIX ".so"
)

3、编写C/C++ 方法

在 include 目录下,新建一个 simple.h 文件,而 src 目录下则相应地创建一个 simple.cpp 文件,记住,头文件和源文件一定要同名。在 simple.h 中声明一个方法原型:

/** Copyright (c) 2025 彭友聪* HMOSThirdLib is licensed under Mulan PSL v2.* You can use this software according to the terms and conditions of the Mulan PSL v2.* You may obtain a copy of Mulan PSL v2 at:http://license.coscl.org.cn/MulanPSL2* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY* KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO* NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.* See the Mulan PSL v2 for more details.* IDE: CLion* Project:  HMOSThirdLib* File:     simple.h* @author:  御承扬* @Email: 2923616405@qq.com* @Date:    2025/8/10* @Time:    13:58* * *///
// Created by pengyoucong on 2025/8/10.
//#ifndef HMOSTHIRDLIB_SIMPLE_H
#define HMOSTHIRDLIB_SIMPLE_H
const char* simpleReturnString();
#endif //HMOSTHIRDLIB_SIMPLE_H

对应的simple.cpp,对该方法进行具体实现:

/** Copyright (c) 2025 彭友聪* HMOSThirdLib is licensed under Mulan PSL v2.* You can use this software according to the terms and conditions of the Mulan PSL v2.* You may obtain a copy of Mulan PSL v2 at:http://license.coscl.org.cn/MulanPSL2* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY* KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO* NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.* See the Mulan PSL v2 for more details.* IDE: CLion* Project:  HMOSThirdLib* File:     simple.cpp* @author:  御承扬* @Email: 2923616405@qq.com* @Date:    2025/8/10* @Time:    14:00* * *///
// Created by pengyoucong on 2025/8/10.
//
#include "simple.h"
const char* simpleReturnString() {return "simpleReturnString:尝试将C/C++源码编译成鸿蒙平台库文件";
}

二、编译库文件

由于 CMake 进行库文件编译的时候,会生成一些配置文件和中间文件,因此,为了不污染项目目录,可以在项目根目录下新建一个专门的目录,用于存放 CMake 输出的中间文件和配置文件,比如新建一个 hmos_ouput 目录,而后在命令行中打开该目录,并使用如下命令:

{HOMS_NDK_HOME}/native/build-tools/cmake/bin/cmake -DCMAKE_TOOLCHAIN_FILE={HOMS_NDK_HOME}/native/build/cmake/ohos.toolchain.cmake -DCMAKE_INSTALL_PREFIX=/output/HMOSThirdLib -DOHOS_ARCH=arm64-v8a .. -L

进行 cmake 编译,而编译成功之后,就会在 hmos_ouput 目录下生成 Makefile,有了这个Makefile后,同样在 hmos_ouput 目录下执行 make 命令,就可以得到最终的制品,而该制品会放在 CMakeLists 中设定的 libs/HMOSThirdLib.so,而由于执行 CMake 操作的目录在 homs_ouput 目录,所以生成的libs也就在该目录下。
在这里插入图片描述

三、使用预编译库

找一个 HarmonyOS NEXT 项目,创建一个 NDK 模块,并将上述得到的 .so 文件即 C/C++ 预编译库,集成到该 NDK 模块中进行使用。

1、引入头文件

将 simple.h 文件从上面的C/C++项目中拷贝一份,并放到 NDK 模块的 src/main/cpp/include 中,为了保证 simple.h 文件能被检索到,修改 NDK 模块的 CMakeLists 文件,加上内容:

include_directories(${NATIVERENDER_ROOT_PATH}${NATIVERENDER_ROOT_PATH}/include)

2、引入库文件

接着,将 ibHMOSThirdLib.so 文件复制一份,并放到 NDK 模块根目录下的libs目录,相应的架构目录中,例如:
在这里插入图片描述
并将该库文件通过 CMakeLists 进行链接,即用 target_link_libraries(learnnapi PUBLIC libace_napi.z.so ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${OHOS_ARCH}/libHMOSThirdLib.so) 进行设置。

3、在 NAPI 中使用 simpleReturnString 方法

由于在鸿蒙APP最终以ArkTS代码编写pages作为应用交互界面,必须先将纯C/C++ 代码通过 NAPI 进行转写才行,所以,我们有必要在 NDK 模块中新增一个 NAPI,不妨就叫 testGetMessage,具体操作如下:

3.1、新增NAPI

打开位于 /src/main/cpp 目录下的 napi_init.cpp 文件,在文件头处新增导包语句:#include "simple.h",并在合适位置新增如下一段代码:

static napi_value testGetMessage(napi_env env, napi_callback_info info) {const char* message = simpleReturnString();napi_value result;napi_status status = napi_create_string_utf8(env, message, strlen(message), &result);return status == napi_ok ? result : nullptr;
}

将该方法注册到 napi_property_descriptor 中:
在这里插入图片描述
而 src/main/cpp/types/index.d.ts 中相应增加内容:
在这里插入图片描述

3.2、使用 NAPI

在这里插入图片描述
如上所示,在 entry 模块或其他 har 包模块,只需将 NDK 模块作为依赖添加到 oh-package.json 文件中,就可以用类似如下的代码去使用 NAPI:

import nativeModule from 'liblearnnapi.so'export class NAPIAdapter {private constructor() {}static Add(x: number, y: number) {return nativeModule.add(x, y);}static NativeCallArkTs(param: number) {return nativeModule.nativeCallArkTS((x: number) => {return x + param;});}static createPerson(name: string, age: number, height: number) {return nativeModule.createPerson(name, age, height);}static parsePerson(param: object) {return nativeModule.parsePerson(param);}static testGetMessage() {return nativeModule.testGetMessage();}
}

在这里插入图片描述
将APP部署到真机上运行,打开日志窗口就可以看到对应的内容输出:
在这里插入图片描述

http://www.dtcms.com/a/324157.html

相关文章:

  • 人工智能-python-机器学习-决策树与集成学习:决策树分类与随机森林
  • 给AI装上“翻译聚光灯”:注意力机制的机器翻译革命
  • ECharts Y轴5等分终极解决方案 - 动态适配缩放场景
  • 【走进Docker的世界】Docker的发展历程
  • MyBatis-Plus 逻辑删除
  • Spark学习(Pyspark)
  • Shell脚本-了解i++和++i
  • wordpress语言包制作工具
  • 点击速度测试:一款放大操作差距的互动挑战游戏
  • 简要介绍交叉编译工具arm-none-eabi、arm-linux-gnueabi与arm-linux-gnueabihf
  • 面向高级负载的 Kubernetes 调度框架对比分析:Volcano、YuniKorn、Kueue 与 Koordinator
  • Z20K118库中寄存器及其库函数封装-PMU库
  • ThreadLocal有哪些内存泄露问题,如何避免?
  • 机器学习实战·第三章 分类(1)
  • SAP HCM 结构化授权函数
  • 计算机网络:路由聚合是手动还是自动完成的?
  • 采用GPT5自动规划实现番茄计时器,极简提示词,效果达到产品级
  • 算术运算符指南
  • 震动马达实现库函数版(STC8)
  • MPLS使用LSP解决路由黑洞
  • 【工具变量】地市城市创业活力数据集(1971-2024年)
  • 微信小程序中实现表单数据实时验证的方法
  • 计算机网络:如何理解目的网络不再是一个完整的分类网络
  • 线程池线程复用的原理是什么?
  • 单调栈通用思路
  • CrackMapExec--安装、使用
  • Matlab算法代码速成5:Matlab求解分段微分方程编程示例
  • Linux环境下实现简单TCP通信(c)
  • Vue 3 快速入门 第五章
  • Jetpack系列教程(二):Hilt——让依赖注入像吃蛋糕一样简单