在上一章小结中,我们已经初步了解了安卓NKD开发的步骤。
本章中主要介绍鸿蒙NDK demo的搭建,重复的名词就不再做讲解。鸿蒙中Arkts与C++通讯的语言为NAPI
前置:下载鸿蒙开发包NDK
记录这里的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文件
整体项目结构如下:
改造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所在文件夹名称也要同步更改。
6、思考
是否可以像android一样集成不需要头文件引用的so