鸿蒙NDK初识

302 阅读2分钟

在上一章小结中,我们已经初步了解了安卓NKD开发的步骤。

本章中主要介绍鸿蒙NDK demo的搭建,重复的名词就不再做讲解。鸿蒙中Arkts与C++通讯的语言为NAPI

前置:下载鸿蒙开发包NDK

image.png

记录这里的Location,后面需要用到

上一章我们使用了IDEA自带的开发工具打包出了SO并使用,鸿蒙中,准备换一个方式,用原始的C文件使用命令行打包SO

1、准备好一个C文件和头文件

add.h:

#include<stdio.h>

int add(int a,int b);

add.cpp:

#include "add.h"

int add(int a ,int b ){

   return a+b ;
}

2、编写打包工具CMakeLists.txt

cmake_minimum_required(VERSION 3.5.0)

project(add)

#包含的头文件内容,若不需要导出这个文件的接口,这里可以不加
include_directories(add.h)

#包含的源文件内容
add_library(add SHARED add.cpp)

#其他需要链接的库文件
target_link_libraries(add PUBLIC libace_napi.z.so)

3、使用CMake命令编译

这里的location为最上面写的sdk目录保存位置

location\15\native\build-tools\cmake\bin\cmake -G Ninja -B out -DCMAKE_TOOLCHAIN_FILE=location\15\native\build\cmake\ohos.toolchain.cmake -DCMAKE_MAKE_PROGRAM=location\15\native\build-tools\cmake\bin\ninja.exe -DCMAKE_BUILD_WITH_INSTALL_RPATH=true

location\15\native\build-tools\cmake\bin\cmake --build out

编译完成,得到一个out文件夹,点进去后即可看到 libadd.so

4、集成项目中使用

因为上述没有打包NAPI的中间桥梁,所以只能新建native工程

将libadd.so放置在entry.libs.arm64-v8a下

cpp.types下新建 add/arm64-v8a,再建立include和lib文件夹,分别放入.h接口头文件和so文件

整体项目结构如下:

image.png

改造CMakeLists.txt文件:


cmake_minimum_required(VERSION 3.5.0)
project(NDKDmeo)

#加入 napi_init.cpp 此文件为沟通桥梁
add_library(entry SHARED napi_init.cpp)

#加入需要的头文件接口
target_include_directories(entry PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/add/${OHOS_ARCH}/include)

#加入源so文件
target_link_libraries(entry PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/add/${OHOS_ARCH}/lib/libadd.so)

#其他链接库
target_link_libraries(entry PUBLIC libace_napi.z.so)

修改napi_init.cpp:

#include "napi/native_api.h"
#include "add/arm64-v8a/include/add.h"


static napi_value Add(napi_env env, napi_callback_info info)
{
    //获取传入的参数
    size_t argc = 2;
    napi_value args[2] = {nullptr};
    napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);
    int value0;
    napi_get_value_int32(env, args[0], &value0);
    int value1;
    napi_get_value_int32(env, args[1], &value1);

    napi_value sum;
    //改为调用C中的头文件信息
    napi_create_int32(env, add(value0 , value1), &sum);
    return sum;
}

至此,第一个so库调用成功

5、扩展

这种方式为项目依赖entry.so,entry.so依赖libadd.so,所以如果有第二个sub.so ,需要扩展:

#CmakeList.txt

# ...

add_library(entry SHARED napi_init.cpp)
#加入第二个so的引用 ,不能与sub.so同名
add_library(suba SHARED napi_sub.cpp)
target_include_directories(entry PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/add/${OHOS_ARCH}/include)
target_include_directories(suba PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/sub/${OHOS_ARCH}/include)

target_link_libraries(entry PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/add/${OHOS_ARCH}/lib/libadd.so)
target_link_libraries(suba PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/sub/${OHOS_ARCH}/lib/libsub.so)

target_link_libraries(entry PUBLIC libace_napi.z.so)
target_link_libraries(suba PUBLIC libace_napi.z.so)

另外对应的源文件中注册模块的名称nm_modname,和.d.ts同级目录下oh-package.json5中的name,以及.d.ts所在文件夹名称也要同步更改。

image.png

6、思考

是否可以像android一样集成不需要头文件引用的so