如何实现ArkTS与C/C++的HashMap转换?

实现ArkTS的HashMap转至Native侧。

HarmonyOS
2024-05-23 22:45:21
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
幸运小面

方案一:传递数组将HashMap的key、value作为数组取出,将两个数组传递至native侧并组装成Map。

ArkTS侧

let start = systemDateTime.getTime(true) 
let keysArray: Array<string> = Array.from(this.myMap.keys()) 
let valuesArray: Array<string> = Array.from(this.myMap.values()) 
testNapi.ts_putMap(keysArray, valuesArray, this.myMap.length) 
let end = systemDateTime.getTime(true) - start 
console.info("传数组耗时:" + end.toString())

Native侧

// 将value转成字符串返回 
static std::string value2String(napi_env env, napi_value value) { 
    size_t stringSize = 0; 
    napi_get_value_string_utf8(env, value, nullptr, 0, &stringSize); // 获取字符串长度 
    std::string valueString; 
    valueString.resize(stringSize + 1); 
    napi_get_value_string_utf8(env, value, &valueString[0], stringSize + 1, &stringSize); // 根据长度传换成字符串 
    return valueString; 
} 
  
  
static static napi_value ts_putMap(napi_env env, napi_callback_info info) { 
  
    std::map<std::string, std::string> myMap; 
  
    size_t argc = 3; 
    napi_value args[3] = {nullptr}; 
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 
  
    napi_value mapKey = args[0];//key 
    napi_value mapVal = args[1];//value 
    napi_value mapNum = args[2];//length 
  
    uint32_t mapCNum = 0; 
    napi_get_value_uint32(env, mapNum, &mapCNum); 
  
    for (uint32_t i = 0; i < mapCNum; i++) { 
        napi_value keyNIndex, valNIndex; 
        napi_get_element(env, mapKey, i, &keyNIndex); 
        napi_get_element(env, mapVal, i, &valNIndex); 
  
        std::string keyIndex = value2String(env, keyNIndex); 
        std::string valIndex = value2String(env, valNIndex); 
        //         OH_LOG_INFO(LOG_APP, "%{public}s %{public}s",keyIndex.c_str(), valIndex.c_str()); 
  
        myMap[keyIndex] = valIndex; 
    } 
    return nullptr; 
}

方案二:传递JSON 将HashMap转为Json数据传至native侧,在native侧反序列化用Map承接。

ArkTS侧转Json

1、JSON.stringify不支持对HashMap操作,需要先将其转成Record

map2rec(map:HashMap<string, ESObject>):Record<string,ESObject>{ 
    // map转Record 
    let Rec:Record<string,ESObject> = {} 
    map.forEach((value:ESObject, key:string) => { 
      if(value instanceof HashMap){//value可能为HashMap 
        let vRec:Record<string,ESObject> = this.map2rec(value) 
        value = vRec 
      } 
      Rec[key] = value 
    }) 
    return Rec 
  }

2、然后使用JSON.stringify序列化

let start = systemDateTime.getTime(true) 
let myRec:Record<string,ESObject> = this.map2rec(this.myMap) 
let str:string = JSON.stringify(myRec) 
testNapi.map_json(str) 
let end = systemDateTime.getTime(true) - start 
console.info("JSON耗时: " + end.toString())

Native侧

        c++没有直接反序列化的接口,需要使用三方库。

         本demo采用lycium交叉编译工具编译json三方库。参考

static napi_value map_json(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); 
  
    std::string jsonStr = value2String(env, args[0]); 
  
    auto myMap = nlohmann::json::parse(jsonStr.c_str()); 
    //     std::string val = myMap.at("key1"); 
    std::string val = myMap.at("arr").at(2); 
    OH_LOG_INFO(LOG_APP, "%{public}s", val.c_str()); 
  
    return nullptr; 
}

测试数据:

  myMap: HashMap<string, ESObject> = new HashMap<string, string>() 
  
  aboutToAppear(): void { 
    for(let i=0;i<10000;i++){ 
      let key:string = "key" + i.toString() 
      let val:string = "value" + i.toString() 
      this.myMap.set(key,val) 
    } 
  }

方案对比:

针对100000条<string,string>类型的数据,两种方案耗时对比如下:(单位:纳秒)

两者耗时相差不大,方案一传递数组略微耗时少一点。

值得考虑的是方案一对于比较复杂的数据,例如value类型也是HashMap或者Array不太适用,需要在native侧多封装一层针对napi_value为复杂类型的处理,代码量略大。

分享
微博
QQ
微信
回复
2024-05-24 22:19:51
相关问题
如何实现ArkTSC/C++数组转换
538浏览 • 1回复 待解决
如何实现ArkTSC/C++对象传递
479浏览 • 1回复 待解决
HarmonyOS ArkTSC/C++交互
510浏览 • 1回复 待解决
如何C/C++ 创建ArkTS对象
2088浏览 • 1回复 待解决
ArkTSC++互相直接调用
1849浏览 • 1回复 待解决
ArkTS/js怎样C++进行交互?
96浏览 • 1回复 待解决
C++ 如何获取操作 Arkts 实例
802浏览 • 1回复 待解决
如何修改C++版本?C++支持情况?
918浏览 • 1回复 待解决
ArkTS对象绑定C++对象如何回收?
795浏览 • 1回复 待解决
c/c++层主动调用ArkTS存在问题
272浏览 • 1回复 待解决
C++调用ArkTS 定义方法
1757浏览 • 1回复 待解决
ArkTSC++之间交互
1199浏览 • 1回复 待解决
ArkTS调用C++类中成员函数
1189浏览 • 1回复 待解决
ts给c++传递数组,c++如何解析
1744浏览 • 1回复 待解决
ArkTS层通过接口访问C++层对象
266浏览 • 1回复 待解决
C++同步调ArkTS里面的方法
960浏览 • 1回复 待解决
AVPlayer实现音频播放(c++侧)
1146浏览 • 1回复 待解决
提问
该提问已有0人参与 ,帮助了0人