如何在WebAssembly中将字符串写入内存

时间:2018-07-06 05:08:03

标签: string webassembly

我开始这样工作:

// example.wast
(module
  (memory (export "mem") 1))

// example.js
WebAssembly.instantiateStreaming(fetch('example.wasm'), {}).then(mod => {
  var exports = mod.instance.exports
  var i8 = new Uint8Array(exports.mem)
  var ra = 100
  var rb = 500
  var rc = 1000
  var rd = 1200
  var re = 2000
  exports.copy(0, ra)
  exports.copy(ra, rb)
  exports.copy(rb, rc)
  exports.copy(rc, rd)
  exports.copy(rd, re)
  console.log(ra, getString(ra, i8))
  console.log(rb, getString(rb, i8))
  console.log(rc, getString(rc, i8))
  console.log(rd, getString(rd, i8))
  console.log(re, getString(re, i8))
})

function getString(index, buffer) {
  var s = ''
  for (var i = index; i < index + size; i++) {
    s += String.fromCharCode(buffer[i])
  }
  return s
}

但是为了实现该copy功能,我首先需要将字符串 load 加载到WebAssembly内存中。想知道我是如何做到的(使用尽可能少的JS,而主要使用WebAssembly代替)。想知道您是否可以这样做:

exports.loadString(index, 'Hello World', i8)

否则,您必须执行以下操作:

function loadString(index, string, buffer) {
  for (var i = 0, n = string.length; i < n; i++) {
    buffer[index + i] = string[i]
  }
}

或更妙的是:

function loadString(index, string, buffer) {
  for (var i = 0, n = string.length; i < n; i++) {
    exports.loadChar(index + i, string[i])
  }
}

想知道如何在WebAssembly中执行此exports.loadCharexports.loadString,在其中将字符串加载到内存中的特定位置。

我想避免使用JS,即buffer[index + i] = string[i]。也许有一种方法可以动态加载到data段中,这将允许exports.loadString

1 个答案:

答案 0 :(得分:0)

WebAssembly没有用于读取/写入线性内存的任何实用程序函数,因此没有导出的exports.loadString函数。

WebAssembly导出对线性内存本身的引用,您可以将其作为类型化数组进行读取/写入。您已经在这里获得了对其的引用:

var i8 = new Uint8Array(exports.mem)

这将创建一个字节数组,该数组允许您读取/写入名称为mem的从模块导出的线性存储器。您需要对字符串进行编码并将其写入此数组:

var encoder = new TextEncoder();
var encodedString = encoder.encode(str);

var i8 = new Uint8Array(exports.mem)

// Copy the UTF-8 encoded string into the WASM memory.
i8.set(encodedString);