【问题标题】:Emscripten pass stl c++ map parameterEmscripten 传递 stl c++ map 参数
【发布时间】:2019-04-29 14:09:31
【问题描述】:

我不知道如何为以下函数调用 JS 生成的代码:

void printmap(const map<string, vector<string> > &ms)
{
    map<string, vector<string> >::const_iterator m1i;
    for (m1i = ms.begin(); m1i != ms.end(); m1i++)
    {
        printf("%s:\n", m1i->first.c_str());
        vector<string>::const_iterator m2i;
        for (m2i = m1i->second.begin(); m2i != m1i->second.end(); m2i++)
            printf("\t%s\n", m2i->c_str());
    }
}

更具体地说,准备'ms'参数的JS是什么样的?

【问题讨论】:

    标签: emscripten


    【解决方案1】:

    使用Embind map and vector 非常可行

    来自网站的示例: C++ 代码

        #include <emscripten/bind.h>
        #include <string>
        #include <vector>
    
        using namespace emscripten;
    
        std::vector<int> returnVectorData () {
          std::vector<int> v(10, 1);
          return v;
        }
    
        std::map<int, std::string> returnMapData () {
          std::map<int, std::string> m;
          m.insert(std::pair<int, std::string>(10, "This is a string."));
          return m;
        }
    
        EMSCRIPTEN_BINDINGS(module) {
          function("returnVectorData", &returnVectorData);
          function("returnMapData", &returnMapData);
    
          // register bindings for std::vector<int> and std::map<int, std::string>.
          register_vector<int>("vector<int>");
          register_map<int, std::string>("map<int, string>");
        }
    

    Js 代码

    var retVector = Module['returnVectorData']();
    
    // vector size
    var vectorSize = retVector.size();
    
    // reset vector value
    retVector.set(vectorSize - 1, 11);
    
    // push value into vector
    retVector.push_back(12);
    
    // retrieve value from the vector
    for (var i = 0; i < retVector.size(); i++) {
        console.log("Vector Value: ", retVector.get(i));
    }
    
    // expand vector size
    retVector.resize(20, 1);
    
    var retMap = Module['returnMapData']();
    
    // map size
    var mapSize = retMap.size();
    
    // retrieve value from map
    console.log("Map Value: ", retMap.get(10));
    
    // figure out which map keys are available
    // NB! You must call `register_vector<key_type>`
    // to make vectors available
    var mapKeys = retMap.keys();
    for (var i = 0; i < mapKeys.size(); i++) {
        var key = mapKeys.get(i);
        console.log("Map key/value: ", key, retMap.get(key));
    }
    
    // reset the value at the given index position
    retMap.set(10, "OtherValue");
    

    以上面的sn-p作为参考,应该不难达到你的要求。

    【讨论】:

      【解决方案2】:

      您可以在 JS 中调用您的 printmap()

      WebAssembly 当前defines number types only:32/64 位整数/浮点数。由于这个限制,Emscripten 编译的 WASM 代码可以通过以下类型与 JS 交互:

      1. 数字类型(整数和浮点数)
      2. 指针类型(通过将整数视为 WASM 内存地址 0x00000000 的偏移量)
        • 字节(或整数)数组的指针
        • 一个字符串的指针(虽然它是isn't simple
        • 类实例的指针(通过Embind

      我不知道指针和引用的行为如何不同,thus you cannot use a reference type to interact with JS

      正如您在这里猜到的那样,没有办法操作像 map&lt;string, vector&lt;string&gt; 这样复杂的 C++ 类型。

      总结一下,我有几点建议给你:

      1. 将引用类型更改为指针。

      void printmap(const map&lt;string, vector&lt;string&gt; &gt; &amp;ms)

      void printmap(const map&lt;string, vector&lt;string&gt; &gt; *ms)

      1. ms写一个init函数,这样你就可以在JS中做这样的事情:
      let map_ptr = module._initmap();
      ...Do something..
      module._printmap(map_ptr);
      
      1. 避免在JS端直接使用这种复杂的C/C++类型,或者为ms制作getter和setter函数。

      【讨论】:

        猜你喜欢
        • 2020-09-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-23
        • 1970-01-01
        • 2014-04-22
        • 1970-01-01
        相关资源
        最近更新 更多