OpenHarmony NDK工具链实战:从环境配置到交叉编译调试
1. OpenHarmony NDK工具到底是什么做 OpenHarmony 开发有一段时间的朋友可能都有过这种体会官方文档把 ArkTS 和 ArkUI 讲得挺细但一旦你想把 C/C 底层的算法库、音视频处理库、自研的静态库接进来或者要碰图形渲染、多线程计算这类“距硬件更近”的活光靠 ArkTS 那层是顶不上的。这时候就需要 OpenHarmony NDK 工具出场了。简单说NDK 就是 OpenHarmony 给开发者提供的一套原生开发工具链它让你能用 C/C 写代码然后编译成可以在 OpenHarmony 系统上直接跑的 .so 动态库或 .a 静态库。配合 DevEco Studio 里的 CMake 构建系统这些库可以被上层的 ArkTS/ArkUI 通过 NAPI 调用也可以作为独立的 native 可执行程序运行在设备上。那“NDK工具”这个系列我打算从上往下拆。上篇聚焦的是“工具本身”SDK 和 NDK 的关系、工具链结构、环境配置、构建参数、调试时的常见坑。后面再讲 NAPI 封装、native 渲染、性能排查这些更贴近业务的东西。这篇文章适合谁看我觉得有三类人已经在做 OpenHarmony 应用开发但一直只碰 ArkTS想往底层走的开发者。要移植 Linux/Android 上的 C/C 库到 OpenHarmony需要搞清楚编译配置差异的人。遇到 native 层崩溃、渲染异常、so 加载失败这类问题想快速建立排查思路的人。先说结论OpenHarmony NDK 工具链本质上是一个以 clang 为基础的交叉编译环境它提供了 sysroot、编译器、CMake toolchain 文件、SDK 中的 native API 头文件以及一套跟 Android NDK 有相似之处但又有明显区别的构建约定。你把它理解成一座桥也行理解成一套“罐头工具”也行关键是得知道它由哪几块组成哪块出了问题会导致什么现象。我记得第一次跑通一个简单的 native hello world折腾了将近半天后来又因为 so 依赖顺序、syscap 检查和 CPU 架构选择不对反复踩坑。这篇就是把那些经验捋一遍尽量让后来的人少绕路。2. 拆解NDK工具链从SDK到sysroot2.1 SDK、NDK和移动应用开发包的关系想搞明白 NDK得先分清一组概念OpenHarmony SDK、OpenHarmony NDK以及我们常说的“移动应用开发包”里那套 SDK/NDK。OpenHarmony SDK 是面向应用开发的完整工具包它包含 API 的 TypeScript 声明、ArkTS 编译支持、SDK 工具以及配套的系统镜像、模拟器相关组件。日常开发 ArkTS 程序时DevEco Studio 依赖的就是这份 SDK。OpenHarmony NDK 是 SDK 里的一个重要组成部分通常在 SDK Manager 里单独勾选安装。它包含交叉编译器clang/clang以及基于 llvm 的工具链。Sysroot一套 OpenHarmony 系统的头文件和库文件镜像编译时用来定位标准库头文件和系统库。CMake toolchain 文件一个名为 ohos.toolchain.cmake 的构建脚本CMake 通过它知道目标平台、编译器、ABI。Native API 头文件比如 napi.h、native_window.h、EGL/GLES 相关的头文件等。构建辅助命令比如用于生成符号表、静态检查的工具。而“移动应用开发包”这个词更多是产业侧对华为移动服务HMS及配套开发能力的统称里面除了 OpenHarmony SDK还包含多设备适配、云开发、AI 服务这些能力。它的 SDK 部分和 NDK 是两回事不要混淆。实际开发中你只要记住一条路径逻辑DevEco Studio 通过 SDK Manager 把 OpenHarmony SDK 拉到本地SDK 里包含 API 版本目录而 NDK 组件是其中一个可选安装项。安装完后你会看到一个类似 sdk/default/openharmony/ndk 的目录里面就是完整的原生工具链。2.2 NDK工具链的核心组件与目录结构不同版本的 OpenHarmony NDK目录结构会有细微差异但核心组件基本固定。以 5.0.0 Release 的典型目录为例ndk/ ├── build-tools/ │ └── ohos-syscall/ ├── cmake/ │ └── ohos.toolchain.cmake ├── etc/ │ └── ... ├── llvm/ │ ├── bin/ │ │ ├── clang │ │ ├── clang │ │ ├── llvm-nm │ │ ├── llvm-objdump │ │ └── ... │ └── lib/ ├── native/ │ ├── sysroot/ │ │ ├── usr/include/ │ │ └── usr/lib/ │ ├── ndk_syscap.json │ └── ... ├── prebuilts/ │ └── ... ├── toolchains/ │ └── ohos-llvm/ └── package.json真正编译时最常打交道的是三个ohos.toolchain.cmake —— CMake 构建的核心配置文件。llvm/bin/clang —— 实际的编译器。native/sysroot —— 目标系统的头文件和库。我第一眼看到这些目录时也有点晕但拆开看就不难了。编译器是 clangCMake 通过 toolchain 文件把编译器指向 clang同时把 sysroot 指向 native/sysroot。sysroot 里是 OpenHarmony 系统的“骨架”编译时头文件从 usr/include 找链接时库文件从 usr/lib 找。整个过程有点像在本地交叉编译一个给嵌入式系统用的程序只不过这个“嵌入式系统”换成了 OpenHarmony。有个容易忽略的细节NDK 自带的是 clang不是 GCC。这是因为 OpenHarmony 的工具链和标准库适配都是基于 LLVM 体系做的sysroot 里的 libc、unwind 等都是 clang 配套的版本。你如果习惯 GCC 的编译选项迁移过来时要特别留意像 -fPIC、-stdc17 这些通用项没问题但一些 GCC 特有的内建函数、宏定义可能在 clang 下行为不同。2.3 为什么用clang而不是GCC这个问题我在实际移植库的时候遇到过某些第三方开源代码用了 GCC 才有的attribute扩展或特定内联汇编语法拿到 clang 下编译会有问题。所以搞清楚官方选型原因能帮你预判很多编译错误。OpenHarmony 选择 clang主要有三个原因LLVM 架构更适合快速适配多目标架构。OpenHarmony 要同时支持 arm64-v8a、armeabi-v7a、x86_64、x86 等多套 ABILLVM 的后端天然支持这些目标出一套 clang 就能覆盖全平台。诊断信息更友好编译期错误提示比 GCC 更直观。对于大型 native 工程这点非常救命。OpenHarmony 自身系统编译也在大量使用 LLVM 工具链统一工具链能减少维护成本。理解这一点之后你就明白了配置 NDK 环境时不要尝试“换成 GCC 试试”那不是捷径而是给自己挖坑。老老实实跟着 clang 的坑走大部分问题都能通过编译选项调优解决。3. 从零开始配置NDK开发环境3.1 第一步通过DevEco Studio安装NDK组件配置 NDK 环境的第一步不是去网上找一个“NDK压缩包”然后解压——虽然有人这么干但很容易因为版本不匹配导致构建失败。官方路径是从 DevEco Studio 的 SDK Manager 里安装。打开 DevEco Studio进入 File Settings SDK Manager可以看到 OpenHarmony SDK 的组件列表其中有一项就是 NDK。勾选后点 Apply它会自动下载。下载完以后建议在本地确认一下这些目录编译器位置sdk/default/openharmony/ndk/llvm/bin/clangtoolchain 文件位置sdk/default/openharmony/ndk/build-tools/cmake/ohos.toolchain.cmakesysroot 位置sdk/default/openharmony/ndk/native/sysroot很多新人第一次配置失败是因为在 DevEco Studio 里建工程时选了“Empty Ability”模板默认不带 native 工程结构。这时你要么创建工程时选择 Native C 模板要么在一个已有工程的 module 上右键 Add C Support让 IDE 自动生成 CMakeLists.txt 和 cpp 目录。3.2 手动配置CMake和toolchain参数DevEco Studio 自动生成模板后大部分构建参数不需要手敲但如果你想在命令行独立构建或者要接入自己的一套 CI 脚本那就得知道这些参数的含义。这是我实际用过的一套命令cmake -S . -B build \ -DCMAKE_TOOLCHAIN_FILE/path/to/ohos-sdk/ndk/build-tools/cmake/ohos.toolchain.cmake \ -DCMAKE_BUILD_TYPERelease \ -DOHOS_ARCHarm64-v8a \ -DOHOS_PLATFORMOHOS \ -DOHOS_STLc_shared \ -DCMAKE_INSTALL_PREFIX./out逐个解释一下这些参数为什么存在CMAKE_TOOLCHAIN_FILE告诉 CMake现在这套构建不是本地编译而是面向 OpenHarmony 的交叉编译。toolchain 文件内部会帮你设置编译器、sysroot、ABI 等一堆东西。OHOS_ARCH指定目标 CPU 架构。常见值有 arm64-v8a、armeabi-v7a、x86_64。模拟器上调试可能会用到 x86_64真机一般是 arm64-v8a。OHOS_PLATFORM指定目标平台为 OHOS对应 sysroot 下的 OpenHarmony 系统头文件和库。OHOS_STL选择 C 标准库的链接方式c_shared 表示动态链接 libc_shared.soc_static 表示静态链接。多模块工程里强烈建议用 c_shared避免多个 so 各自带一份 STL导致单例和异常跨模块出问题。CMAKE_INSTALL_PREFIX安装输出路径通常是把 so 和头文件放到一个约定目录。需要特别注意OHOS_ARCH 和设备 CPU 架构不匹配时最典型的现象是 so 在推送到设备后用 import 或 dlopen 加载时报 “dlopen failed: cannot locate symbol” 或者 “has unexpected e_machine” 这类错误。出现这种问题第一步先看看你编译的. so 用的什么架构第二步看看设备是什么架构别急着改代码。3.3 编写并构建第一个native库我习惯用一个最简工程验证工具链是否可用下面这套结构就是最小可运行的demo/ ├── CMakeLists.txt ├── cpp/ │ ├── native_hello.cpp │ └── CMakeLists.txtCMakeLists.txt 顶层cmake_minimum_required(VERSION 3.5.0) project(demo) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) add_subdirectory(cpp)cpp/CMakeLists.txtadd_library(native_hello SHARED native_hello.cpp) target_include_directories(native_hello PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) set_target_properties(native_hello PROPERTIES OUTPUT_NAME native_hello LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/libs)cpp/native_hello.cpp#include napi/native_api.h #include cstdint #include string static napi_value Greet(napi_env env, napi_callback_info info) { napi_value result; std::string message hello from native; napi_create_string_utf8(env, message.c_str(), message.size(), result); return result; } EXTERN_C_START static napi_value Init(napi_env env, napi_value exports) { napi_property_descriptor desc[] { {greet, nullptr, Greet, nullptr, nullptr, nullptr, napi_default, nullptr} }; napi_define_properties(env, exports, 1, desc); return exports; } EXTERN_C_END static napi_module demoModule { .nm_version 1, .nm_flags 0, .nm_filename nullptr, .nm_register_func Init, .nm_modname native_hello, .nm_priv ((void*)0), .reserved { 0 }, }; extern C __attribute__((constructor)) void RegisterModule(void) { napi_module_register(demoModule); }这段代码其实已经不是一个纯 C/C 测试而是带上了 NAPI 注册逻辑。之所以一开始就按这种结构来是因为 OpenHarmony 的 native 库最终几乎都要通过 NAPI 接口跟 ArkTS 交互。你提前把 napi_module 注册逻辑写好后面就不用反复改结构。构建命令用上面 3.2 那套我习惯把 OHOS_ARCH 和 OHOS_STL 单独提出来写进一个 build.sh#!/bin/bash OHOS_SDK_HOME$HOME/ohos-sdk cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE$OHOS_SDK_HOME/ndk/build-tools/cmake/ohos.toolchain.cmake -DOHOS_ARCHarm64-v8a -DOHOS_STLc_shared -DCMAKE_BUILD_TYPEDebug cmake --build build --target native_hello -j 8编译完成后在 build/libs 下会生成 libnative_hello.so。把这个 so 放到工程里再在 ArkTS 层用import native_hello from libnative_hello.so就能调用 greet 函数。这个验证链路通了说明你本机的 NDK 工具链基本没问题。4. Syscap、ABI与系统API匹配4.1 Syscap到底管什么编译 OpenHarmony native 代码时经常能看到一个词syscap全称是 System Capability中文叫系统能力。syscap 是一个描述“当前 API 需要哪些系统能力支持”的机制。为什么 NDK 编译时也要关注 syscap因为 OpenHarmony 是一个面向多种设备的系统不同设备支持的系统能力不一样。比如一个跑在轻量设备上的版本可能就不支持某些图形、多媒体接口。你在编译器里直接声明了调用了某个 API编译器虽然不会报错但到运行时会因为没有对应能力而崩溃或返回错误。syscap 检查工具提供了一份 JSON 映射表位于 NDK 目录下通常叫 ndk_syscap.json。它把每个 API 和对应的系统能力关联起来DevEco Studio 在构建时也会参考这份表做静态检查。我在一次适配中因为没有检查某个 API 是否被目标系统支持结果跑到上一代设备上就闪退排查了半天。建议做法在代码里调用任何非基础的 native API 前先查一下 ndk_syscap.json确认目标设备的 system version 支持。也可以在代码里用系统提供的OH_NativeSystem_GetSystemCapability之类接口做运行时判断但常用场景还是先做静态确认减少运行时分支。4.2 x86、ARM与模拟器适配搜索热词里有一个“OpenHarmony x86”这其实点出了一个常见误区有些开发者以为 OpenHarmony 应用只需要支持 ARM 架构因为手机基本都是 ARM。但如果你在模拟器上调试模拟器的 CPU 可能是 x86_64这时候 native 库必须编译 x86_64 版本否则加载必然失败。OpenHarmony NDK 支持的架构主要有四套架构ABI 名称常见场景64位ARMarm64-v8a当前绝大多数真机32位ARMarmeabi-v7a老旧设备或兼容模式64位x86x86_64模拟器、某些平板/桌面形态32位x86x86极少见一般不用构建时如何选择我的经验是发布到真机市场至少编 arm64-v8a。如果产品还兼容老设备再加 armeabi-v7a。模拟器联调编 x86_64。如果工程最终要同时支持真机和模拟器那就用 CMake 的 multi-abi 机制分别编译后再合到一个 App 里不要手动叠加。我之前踩过一个很蠢的坑工程 CMakeLists 里写死了 arm64-v8a模拟器上一直闪退报错信息是 ‘dlopen failed: “/data/app/.../lib/arm64/libnative_hello.so” is 64-bit instead of 32-bit’ 之类的提示。其实就是模拟器是 x86_64但你只放了 arm64 的 so。这个认识到位之后排查只需要 30 秒。4.3 链接时的依赖顺序与符号可见性native 开发里还有一类很隐蔽的问题so 能编过但运行时“cannot locate symbol”。原因通常是链接顺序不对。Unix 系链接器处理动态库依赖时是按命令行里的出现顺序从左到右解析的。如果你有这么一段 CMake 配置target_link_libraries(native_hello PUBLIC libthird_party.so)但 libthird_party.so 又依赖 libbase.so而你没有显式把 libbase.so 加到链接参数里那么在严格模式下会报未定义符号。OpenHarmony 的链接器校验比某些嵌入式交叉编译环境要严格依赖链不完整直接编不过。解决办法有两个方向尽量让每个 .so 的依赖闭环不要出现跨 so 的隐式依赖。链接时把所有依赖都显式写出来顺序从底层到上层。比如target_link_libraries(native_hello PUBLIC third_party base)另一个需要留意的点符号可见性。OpenHarmony native 模块加载时默认会做符号解析。如果你的 so 里定义了很多全局符号可能导致符号冲突。更稳妥的做法是设置隐藏符号只导出 NAPI 注册需要的接口在 CMake 里加编译选项target_compile_options(native_hello PRIVATE -fvisibilityhidden)这样导出的动态符号会被压缩到最少既减少加载时间也降低符号冲突概率。5. 调试与异常排查从崩溃日志到渲染问题5.1 hdc与日志系统的使用NDK 开发有一个绕不开的调试对象程序崩溃。ArkTS 层的异常有比较清晰的堆栈但 native 层崩溃往往只有一个 signal 编号和几行寄存器信息看着像天书。好在 OpenHarmony 提供了 hdc 工具HarmonyOS Device Connector类似 Android 的 adb。常用命令我整理一下# 查看已连接设备 hdc list targets # 进入设备 shell hdc shell # 抓取系统日志 hdc hilog # 带过滤条件抓日志 hdc hilog | grep Demo # 推送文件到设备 hdc file send ./libnative_hello.so /data/local/tmp/ # 从设备拉文件 hdc file recv /data/log/hilog.log ./native 崩溃时hilog 里通常会有如下关键信息Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR) #0 pc 00000000000234a /data/app/.../libnative_hello.so #1 pc 000000000001217 /data/app/.../libnative_hello.so看到 pc 地址后不要慌。用 NDK 自带的 llvm-addr2line 或 llvm-symbolizer 把地址翻译成源码行号$OHOS_NDK_HOME/llvm/bin/llvm-addr2line \ -e build/libs/libnative_hello.so \ -f -C 00000000000234a前提是编译时保留了符号表也就是 CMAKE_BUILD_TYPE 不能是 Release至少要 RelWithDebInfo 或 Debug。如果已经是 Release符号被剥离了那只能靠日志和加点排查代码来定位。我把这个流程总结了四步遇到 native 崩溃先走一遍用 hdc hilog 抓崩溃日志确认 signal 类型和崩溃地址。找到对应的 so确认编译时架构和设备匹配。用 llvm-addr2line 转到源码行号。根据行号查空指针、内存越界、生命周期释放问题。这套流程救过我很多次强烈建议每个 native 开发者的工作流里都配上。5.2 从渲染异常反推native层问题搜索热词里有“OpenHarmony画面渲染异常”这个话题如果放到 native 层讲通常涉及 OpenGL ES / EGL 的使用。很多应用不是直接用 OpenGL 画 UI而是在 native 侧做视频帧处理、特效滤镜或者自绘渲染再把结果上屏。常见的 native 渲染异常有这几类渲染结果黑屏或花屏。画面闪烁、撕裂tearing。纹理内容不对像是没更新一样。某些设备上正常某些设备上异常。排查这类问题我的建议是先别盯着 shader 和算法看先把渲染链路拆开确认EGL 是否初始化成功。很多黑屏问题其实是 EGL context 创建失败但代码里没检查返回值。Buffer 的宽度、高度、格式是否匹配。OpenHarmony 使用 native window 和 buffer queue如果 buffer 的像素格式和窗口配置不一致出花屏非常正常。交换缓冲区是否挂在正确的时机。OpenGL ES 的 eglSwapBuffers 要在渲染线程里调用不能和 CPU 侧写同一个 buffer 冲突。比如你用 native_window 创建窗口再通过 OH_NativeWindow_NativeWindowHandleOpt 设置 buffer 格式如果设置的 color gamut 不是设备支持的渲染出来的画面颜色会明显不对。这时候别去调 shader先看一下 buffer 配置。如果你负责的是 UI 层 ArkTS native 混合渲染还要确认一件事native 侧的 EGL surface 是否与 ArkUI 的显示层有冲突。这个问题的排查思路是做分层验证先只跑纯 native surface 的渲染再叠加 ArkUI看看异常是否出现。这样能快速定位是 native 渲染本身的问题还是 UI 合成链路的问题。5.3 用日志验证API调用返回值native 调试最容易被忽略的是系统 API 的返回值。OpenHarmony 的 NDK API 大多会返回错误码比如 OH_NativeWindow_* 系列函数返回一个 NativeWindowOperationResultEGL 相关函数返回 EGLBoolean很多人在代码里直接忽略这些返回值。我见过一个渲染异常的真实案例程序在 ArkTS 层调用一个 native 函数传入了一个无效的 surface 句柄native 层没检查参数直接往下走结果 EGL 初始化失败黑屏。最后是把每个关键 API 的返回值打日志才发现是入参 surface 的 native window 指针已经失效了。所以在 native 代码里我给团队立了一条规矩凡是系统 API返回的错误码必须显式处理至少打一条 hilog自己封装的接口也要在有“外部传入参数”的边界处做校验。很多看起来玄乎的渲染异常、崩溃最后都是这种低级问题。6. 常见NDK配置与编译问题速查下面的表格是我在实际适配中遇到频率最高的几个问题整理出来当作速查表现象常见原因处理方式编译时报找不到头文件比如 napi.h not found没有正确配置 NDK sysroot或者 toolchain 路径不对确认 CMAKE_TOOLCHAIN_FILE 指向 ohos-sdk 实际 NDK 路径并编译前打开 verbose 看头文件搜索路径dlopen failed: cannot locate symbolso 依赖链不完整或者某个依赖 so 未打包进应用检查 target_link_libraries 的依赖顺序把底层库排在后面运行时提示 e_machine 不符编译架构和设备架构不一致确认 OHOS_ARCH 与目标设备匹配模拟器注意用 x86_64native 崩溃但堆栈没有符号编译类型为 Release或符号被 strip改 Debug 或 RelWithDebInfo并在打包时保留 .so 符号多模块同时使用 STL 出现崩溃某些 so 用静态 STL某些用动态 STLSTL 实例冲突统一用 c_shared确保所有 native 模块按相同 STL 模式编译EGL 初始化失败传入的 native window 无效或者 buffer 配置不被支持先打印 surface 指针和 buffer 配置再用最简单的 eglCreateWindowSurface 验证渲染黑屏可能是 EGL context 创建失败或 buffer 格式不一致检查每个 EGL 调用的返回值打印日志后逐步定位除了这张表还有几个实践中的注意点值得单独拎出来说。第一个NDK 版本与 SDK 版本要配套。虽然 DevEco Studio 一般会帮你管好但如果你在一个工程里手动替换了 NDK 目录可能导致 NAPI 头文件版本和系统镜像版本不一致出现“找不到接口”或运行时行为不一致。最好用 SDK Manager 管理的版本不要手动下完整 NDK 替换。第二个编译选项过度优化问题。clang 在高优化级别下-O2、-O3 可能对未定义行为比较敏感导致代码在 Debug 正常、Release 崩溃。排查时先把出问题的模块切到 -O0 -g如果恢复正常那就要怀疑代码里的未定义行为而不是编译器问题。第三个不要在主线程做重型 native 初始化。OpenHarmony 的主线程有 UI 调度职责如果你在 NAPI 的某个同步接口里直接做大量文件读取、模型加载、图像处理可能导致画面卡顿甚至 watchdog 误杀。正确做法是把耗时操作切到工作线程或者用 NAPI 的异步接口返回 Promise。6.1 给新手的“能跑就行”配置模板如果你只想要一个马上能跑的模板下面这套配置是我测试过可用的最小方案cmake -S . -B build \ -DCMAKE_TOOLCHAIN_FILE$OHOS_SDK_HOME/ndk/build-tools/cmake/ohos.toolchain.cmake \ -DOHOS_ARCHarm64-v8a \ -DOHOS_STLc_shared \ -DCMAKE_BUILD_TYPEDebug然后cmake --build build -j 8只要 ohos-sdk 路径正确一般能顺利生成 lib*.so。真正写业务代码时再逐步加入 syscap 检查、符号裁剪、多架构编译这些加固项。6.2 为什么坚持用命令行而不是只靠IDE移动端开发里许多人的习惯是点 IDE 的 Run 按钮编译构建过程被 IDE 包装得很好出问题也只在面板上看一段输出。但做 native 开发我强烈建议至少熟悉命令行构建。原因是IDE 的报错信息经过一层封装遇到 C/C 编译错误时有时会丢关键上下文。而命令行直接跑 cmakec 编译器的报错会原样输出排查问题快得多。另外CI/CD 环境基本上都是命令行构建你如果只会点 IDE后面做自动化打包会被卡住。7. 工具链使用过程中的个人体会这个标题写的是“OpenHarmony NDK工具上”写到这里其实核心工具链的坑已经过了一遍。我个人最大的体会是OpenHarmony NDK 并不难难点在于“习惯切换”。用过 Android NDK 的人会发现两者很多概念相似但细节完全不同没接触过 cross compile 的人则要先适应“交叉编译”这个思维模型。一旦你建立了一个清晰的框架工具链是 clang、构建系统是 CMake、目标系统是 sysroot、系统能力是 syscap后面遇到的大部分问题都能自己找到答案。最后再分享一个我用起来很顺的步骤组合每次新工程初始化时先做一次纯 native 的编译验证再接入 NAPI最后才写 UI 层调用。每次改动只动一个变量出问题定位范围小。后续如果有机会我打算在“下篇”里重点展开 NAPI 的数据类型映射以及多线程环境下怎么安全调用 native 接口。到时候再聊。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →