RN C++ TurboModule中如何通过JSI桥接UInt8Array?附方案对比
React Native TurboModules(JSI)桥接UInt8Array的处理方案对比
一、C++端直接处理UInt8Array
当JSI把UInt8Array解析为jsi::Pointer时,本质是因为它属于TypedArray类型,你可以通过以下步骤直接读取原始字节数据:
- 将
jsi::Value转换为jsi::TypedArray:
// 假设传入的参数是jsi::Value& value if (!value.isObject()) { // 处理非对象错误 return; } jsi::Object obj = value.asObject(); jsi::Runtime& rt = /* 你的JSI Runtime实例 */; jsi::TypedArray uint8Array = obj.asTypedArray(rt); // 确认是UInt8类型 if (uint8Array.type() != jsi::TypedArray::Type::Uint8) { // 处理类型不匹配错误 return; }
- 获取字节数据指针和长度:
// 获取原始数据指针 uint8_t* data = reinterpret_cast<uint8_t*>(uint8Array.data(rt)); // 获取数组长度 size_t length = uint8Array.length(rt); // 此时可以直接操作data和length,比如还原为字符串(因为是TextEncoder编码后的结果) std::string decodedStr(reinterpret_cast<char*>(data), length);
注意:操作完数据后无需手动释放内存,JSI会自动管理TypedArray的内存生命周期。
二、转为Base64传输
如果不想处理TypedArray的底层细节,也可以在JS端将UInt8Array转成Base64字符串,再传递给C++端解码:
JS端转换
// 假设uint8Array是TextEncoder编码后的结果 const base64Str = btoa(String.fromCharCode(...uint8Array)); // 调用TurboModule方法传递base64Str
C++端解码
C++端需要实现Base64解码逻辑(或使用成熟的Base64库),将字符串还原为字节数组,再转为字符串:
// 示例Base64解码函数(简化版,实际建议用可靠实现) std::vector<uint8_t> base64Decode(const std::string& base64) { // 实现Base64解码逻辑 } // 处理传入的base64字符串 std::vector<uint8_t> bytes = base64Decode(base64Str); std::string decodedStr(reinterpret_cast<char*>(bytes.data()), bytes.size());
三、两种方案的优缺点对比
直接处理UInt8Array
- 优点:
- 无额外编码/解码开销,性能最优,适合大体积数据传输
- 直接操作原始字节,避免数据体积膨胀
- 缺点:
- 需要熟悉JSI的TypedArray API,代码复杂度稍高
- 需注意类型校验(确保是UInt8类型),否则可能出现内存访问错误
转为Base64传输
- 优点:
- 代码逻辑简单,无需处理JSI的TypedArray底层细节
- 传输的是标准字符串,兼容性好,不易出现类型匹配问题
- 缺点:
- Base64编码会让数据体积增大约33%,大数据场景下会增加传输开销
- 额外的编码/解码步骤会带来性能损耗
选型建议
如果你的数据量较小(比如几KB以内),用Base64更省心;如果是大体积数据(比如图片、大文本),直接处理UInt8Array能获得更好的性能和更低的内存占用。
内容的提问来源于stack exchange,提问作者Teodor Ciuraru
相关产品推荐
相关产品推荐

