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

鸿蒙 NDK开发:Node-API创建和获取String值(九)

NDK开发中,字符串交互是跨语言通信的基础。Node-API提供了8个用于string值的创建和获取的接口,支持UTF-8、UTF-16、Latin-1、ASCII等多种编码。

一、字符串编码

编码说明
ASCII7位编码,只能表示英文字母、数字和基本符号
UTF-8变长编码,全球范围字符集,互联网广泛使用
UTF-1616位编码,适用于较大字符集
ISO-8859-1(Latin-1)单字节编码,主要表示拉丁字母字符集

二、核心接口

接口描述起始版本
napi_get_value_string_utf8ArkTS字符串 → UTF-8编码C字符串10
napi_create_string_utf8UTF-8 C字符串 → ArkTS string值10
napi_get_value_string_utf16ArkTS字符串 → UTF-16编码C字符串10
napi_create_string_utf16UTF-16 C字符串 → ArkTS string值10
napi_get_value_string_latin1ArkTS字符串 → Latin-1编码C字符串10
napi_create_string_latin1Latin-1 C字符串 → ArkTS string值10
napi_create_external_string_utf16外部UTF-16缓冲区 → ArkTS string(零拷贝)22
napi_create_external_string_ascii外部ASCII缓冲区 → ArkTS string(零拷贝)22

三、使用示例

3.1 napi_get_value_string_utf8

将ArkTS的字符类型数据转换为UTF-8编码的字符。

static napi_value GetValueStringUtf8(napi_env env, napi_callback_info info) { size_t argc = 1; napi_value args[1] = {nullptr}; napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); // 获取字符串长度 size_t length = 0; napi_status status = napi_get_value_string_utf8(env, args[0], nullptr, 0, &length); if (status != napi_ok) { OH_LOG_ERROR(LOG_APP, "napi_get_value_string_utf8 failed"); return nullptr; } // 分配缓冲区并获取字符串内容 char *buf = new char[length + 1]; std::memset(buf, 0, length + 1); status = napi_get_value_string_utf8(env, args[0], buf, length + 1, &length); // 创建ArkTS字符串返回 napi_value result = nullptr; status = napi_create_string_utf8(env, buf, length, &result); delete[] buf; return result; }

接口声明(index.d.ts)

export const getValueStringUtf8: (param: string | number) => string | undefined;

ArkTS调用

hilog.info(0x0000, 'testTag', 'Result: %{public}s', testNapi.getValueStringUtf8('aaBC+-$%^你好123'));

3.2 napi_create_string_utf8

通过UTF-8编码的C字符串创建ArkTS string值。

static napi_value CreateStringUtf8(napi_env env, napi_callback_info info) { const char *str = u8"你好, World!, successes to create UTF-8 string! 111"; size_t length = strlen(str); napi_value result = nullptr; napi_status status = napi_create_string_utf8(env, str, length, &result); if (status != napi_ok) { napi_throw_error(env, nullptr, "Failed to create UTF-8 string"); return nullptr; } return result; }

ArkTS调用

hilog.info(0x0000, 'testTag', 'napi_create_string_utf8:%{public}s', testNapi.createStringUtf8());

3.3 napi_get_value_string_utf16

将ArkTS字符串转换为UTF-16编码的字符。

static napi_value GetValueStringUtf16(napi_env env, napi_callback_info info) { size_t argc = 1; napi_value args[1]; napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); char16_t buffer[MAX_BUFFER_SIZE]; size_t bufferSize = MAX_BUFFER_SIZE; size_t stringLen; napi_get_value_string_utf16(env, args[0], buffer, bufferSize, &stringLen); napi_value result = nullptr; napi_create_string_utf16(env, buffer, stringLen, &result); return result; }

ArkTS调用

let result = testNapi.getValueStringUtf16('hello,'); hilog.info(0x0000, 'testTag', 'napi_get_value_string_utf16:%{public}s', result);

3.4 napi_create_string_utf16

创建一个UTF-16编码的ArkTS字符串。

static napi_value CreateStringUtf16(napi_env env, napi_callback_info info) { const char16_t *str = u"你好, World!, successes to create UTF-16 string! 111"; size_t length = NAPI_AUTO_LENGTH; napi_value result = nullptr; napi_status status = napi_create_string_utf16(env, str, length, &result); if (status != napi_ok) { napi_throw_error(env, nullptr, "Failed to create UTF-16 string"); return nullptr; } return result; }

3.5 napi_get_value_string_latin1

将ArkTS字符串转换为ISO-8859-1编码。

static napi_value GetValueStringLatin1(napi_env env, napi_callback_info info) { size_t argc = 1; napi_value args[1] = {nullptr}; napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); char buf[MAX_BUFFER_SIZE]; size_t length = 0; napi_value napi_Res = nullptr; napi_status status = napi_get_value_string_latin1(env, args[0], buf, MAX_BUFFER_SIZE, &length); if (status != napi_ok) { return nullptr; } napi_create_string_latin1(env, buf, length, &napi_Res); return napi_Res; }

注意:ISO-8859-1编码不支持中文,传入中文字符会乱码。

3.6 napi_create_external_string_utf16(API 22+)

通过外部UTF-16编码的字符串缓冲区创建ArkTS字符串值,避免内存拷贝

// 定义析构回调函数,在GC时释放外部资源 static void StringFinalizerUTF16(void* data, void* hint) { delete[] static_cast<char16_t*>(data); } static napi_value CreateExternalStringUtf16(napi_env env, napi_callback_info info) { const char16_t source[] = u"你好, World!, successes to create UTF-16 string! 111"; int char16tLength = sizeof(source) / sizeof(char16_t); char16_t* str = new char16_t[char16tLength]; std::copy(source, source + char16tLength, str); napi_value result = nullptr; napi_status status = napi_create_external_string_utf16( env, str, NAPI_AUTO_LENGTH, StringFinalizerUTF16, // GC时回调释放str nullptr, &result ); if (status != napi_ok) { delete[] str; napi_throw_error(env, nullptr, "Failed to create utf16 string"); return nullptr; } return result; }

工作原理:外部字符串受GC管理,当ArkTS string生命周期结束被GC回收时,会触发StringFinalizerUTF16函数释放Native侧资源。

3.7 napi_create_external_string_ascii(API 22+)

通过外部ASCII编码的字符串缓冲区创建ArkTS字符串值,避免内存拷贝

static void StringFinalizerASCII(void* data, void* hint) { delete[] static_cast<char*>(data); } static napi_value CreateExternalStringAscii(napi_env env, napi_callback_info info) { const char source[] = "hello, World!, successes to create ASCII string! 111"; int charLength = sizeof(source) / sizeof(char); char* str = new char[charLength]; std::copy(source, source + charLength, str); napi_value result = nullptr; napi_status status = napi_create_external_string_ascii( env, str, NAPI_AUTO_LENGTH, StringFinalizerASCII, nullptr, &result ); if (status != napi_ok) { delete[] str; napi_throw_error(env, nullptr, "Failed to create ascii string"); return nullptr; } return result; }

重要

  • str指向的内存必须在ArkTS string对象的整个生命周期内保持有效

  • 调用接口后,str指向的内存内容必须保持不可变

  • 任何对该内存的写入操作都可能导致程序崩溃

四、CMakeLists.txt配置

如需在Native C++中打印日志:

add_definitions( "-DLOG_DOMAIN=0xd0d0" ) add_definitions( "-DLOG_TAG=\"testTag\"" ) target_link_libraries(entry PUBLIC libace_napi.z.so libhilog_ndk.z.so)

添加头文件:#include "hilog/log.h"

五、8个string接口

接口方向编码拷贝方式
napi_get_value_string_utf8ArkTS → NativeUTF-8拷贝
napi_create_string_utf8Native → ArkTSUTF-8拷贝
napi_get_value_string_utf16ArkTS → NativeUTF-16拷贝
napi_create_string_utf16Native → ArkTSUTF-16拷贝
napi_get_value_string_latin1ArkTS → NativeLatin-1拷贝
napi_create_string_latin1Native → ArkTSLatin-1拷贝
napi_create_external_string_utf16Native → ArkTSUTF-16零拷贝
napi_create_external_string_asciiNative → ArkTSASCII零拷贝

5.2 使用建议

场景推荐接口
通用文本交互UTF-8系列接口
需要支持中文等Unicode字符UTF-8/UTF-16系列接口
仅需处理西欧语言Latin-1系列接口
大数据量、追求性能external string系列接口(零拷贝)

5.3 注意事项

注意事项说明
Latin-1不支持中文传入中文字符会乱码
external string不可变创建后内存内容不能修改
GC回收机制external string在GC时触发finalizer释放Native资源
返回值判断接口返回napi_string_expected表示传入值不是字符串类型
http://www.cnnetsun.cn/news/3073277.html

相关文章:

  • 基于 Simulink 的双向 DC-DC 变换器在低电压大电流下的同步整流(SR)驱动仿真实战教程
  • HarmonyOs开发--设置屏幕朝向 orientation (横竖屏场景)
  • 二升三年级暑假特色作业(pdf图文版)
  • 斯坦福CS146S课程 提示词工程全解(第1周):6大核心技术从原理到代码实战
  • 如何将VR视频转换为2D格式:VR-Reversal完整指南
  • MySQL数据分析入门:从SQL查询到实战电商案例全解析
  • 基于HarmonyOS 7.0 跨端开发的篆刻印章设计页面实战
  • 基于HarmonyOS 7.0 跨端开发的化石猎人采集指南页面实战
  • TVA与具身智能深度融合的内在必然性(7)
  • 从Vgs到VCO:用拉扎维《模拟CMOS》的核心概念,手把手拆解一个PLL设计流程
  • Sunshine游戏串流服务器:打造你的终极跨平台游戏串流系统
  • 量子机器学习在湍流模拟中的创新应用
  • 设计高可用后端架构需要考虑的五个关键点
  • 单通道EEG实现非侵入式脑机接口图像重建技术
  • 终极GPU内存检测方案:MemtestCL专业显卡稳定性验证指南
  • 30天无限续杯:JetBrains IDE试用期重置的完整指南
  • 面向Shopify卖家的最佳AI营销工具栈:选对组合,提升广告转化率
  • 网络安全学习130天
  • 树莓派5到手第一步:保姆级Ubuntu 24.04 Server无头安装与SSH配置(含阿里云镜像加速)
  • Steam Deck模拟器终极指南:如何用EmuDeck一键搭建30+游戏平台
  • 模块化脑机接口系统设计与工程实践
  • 量子误差缓解技术:从噪声建模到PEC实现
  • 自动化诊断平台架构与MTTR优化实践
  • 量子计算在热化学中的应用与W4-11数据集分析
  • 量子计算在化学模拟中的革命性应用与挑战
  • 边缘AI计算新突破:超维计算芯片解析与应用
  • FPGA加速稀疏卷积:原理、实现与性能优化
  • MySQL数据分析入门:从零搭建环境到电商实战案例
  • DAY3 编码器接口
  • Yahoo Finance API:构建企业级金融数据解决方案的.NET实践指南