Emscripten 传递 stl c++ map 参数

Emscripten pass stl c++ map parameter

我不知道如何为以下函数调用 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 是什么样子的?

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

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

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

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

正如您在这里猜到的那样,没有办法操纵像 map<string, vector<string>.

这样复杂的 C++ 类型

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

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

void printmap(const map<string, vector<string> > &ms)

void printmap(const map<string, vector<string> > *ms)

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

使用 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");

以上片段作为参考,应该不难达到你的要求。