当前位置: 首页 > 面试题库 >

如何从WebAssembly函数返回JavaScript字符串

蒲深
2023-03-14
问题内容

如何从WebAssembly函数返回JavaScript字符串?

下列模块可以用C(++)编写吗?

export function foo() {
  return 'Hello World!';
}

另外:我可以将其传递给JS引擎进行垃圾回收吗?


问题答案:

WebAssembly本身不支持字符串类型,它,而支撑件i32/i64/f32/f64值类型以及i8/i16用于存储。

这取决于您要执行的操作,但似乎直接访问缓冲区是最简单的:

const bin = ...; // WebAssembly binary, I assume below that it imports a memory from module "imports", field "memory".
const module = new WebAssembly.Module(bin);
const memory = new WebAssembly.Memory({ initial: 2 }); // Size is in pages.
const instance = new WebAssembly.Instance(module, { imports: { memory: memory } });
const arrayBuffer = memory.buffer;
const buffer = new Uint8Array(arrayBuffer);

如果您的模块具有start功能,那么它将在实例化时执行。否则,您可能会调用一个导出,例如instance.exports.doIt()

完成后,您需要获取字符串大小+内存中的索引,还可以通过导出将其公开:

const size = instance.exports.myStringSize();
const index = instance.exports.myStringIndex();

然后,您将从缓冲区中读取它:

let s = "";
for (let i = index; i < index + size; ++i)
  s += String.fromCharCode(buffer[i]);

请注意,我正在从缓冲区读取8位值,因此我假设字符串是ASCII。那就是std::string给你的东西(内存中的索引就是.c_str()返回的东西),但是要暴露其他东西(例如UTF-8),您需要使用支持UTF-8的C++库,然后自己从JavaScript中读取UTF-8,获得代码点,然后使用String.fromCodePoint

您还可以依靠以null终止的字符串,我在这里没有这样做。

您也可以使用TextDecoderAPI,一旦它获得更广泛的浏览器中创建一个ArrayBufferViewWebAssembly.Memorybuffer(这是ArrayBuffer)。

相反,如果您正在执行从WebAssembly到JavaScript的登录等操作,则可以公开Memory上述内容,然后从WebAssembly声明一个导入,该导入以size+ position调用JavaScript。您可以将模块实例化为:

const memory = new WebAssembly.Memory({ initial: 2 });
const arrayBuffer = memory.buffer;
const buffer = new Uint8Array(arrayBuffer);
const instance = new WebAssembly.Instance(module, {
    imports: {
        memory: memory,
        logString: (size, index) => {
            let s = "";
            for (let i = index; i < index + size; ++i)
                s += String.fromCharCode(buffer[i]);
            console.log(s);
        }
    }
});

需要注意的是,如果您增加了内存(通过使用JavaScript的JavaScriptMemory.prototype.grow或使用grow_memory操作码),则内存将ArrayBuffer被清除,您需要重新创建内存。

垃圾收集器:WebAssembly.Module/WebAssembly.Instance/WebAssembly.Memory是由JavaScript引擎收集到的所有垃圾,但是这是一个相当大的锤子。您可能希望使用GC字符串,而对于位于中的对象,目前尚无法实现WebAssembly.Memory



 类似资料:
  • 问题内容: 在SO中多次问过这个问题。但是我还是收不到东西。 我想从回调中获得一些价值。请看下面的脚本进行澄清。 如果我尝试返回该值,则只是“未定义”。我遵循了SO的一些想法,但仍然失败。 那些是: 问题答案: 这是不可能的,因为您无法从同步方法内部的异步调用返回。 在这种情况下,您需要将回调传递给foo,该回调将接收返回值 问题是,如果内部函数调用是异步的,则所有“包装”此调用的函数也必须是异步

  • 问题内容: 当我尝试读取add函数的返回值时,它什么也不返回。 而且,当我尝试将消息放入变量并从外部返回时,也给出空值。 问题答案: 简单地说, 您不能 。要从此类函数获取值,必须使用回调: 然后,您将使用如下功能:

  • 问题内容: 我正在寻找一个php函数,该函数将接受一个输入字符串,并通过去除所有仅保留字母数字的特殊字符来返回其净化版本。 我需要另一个功能相同但仅返回字母字符AZ的函数。 任何帮助,不胜感激。 问题答案: 警告:请注意,英语不仅限于AZ。 尝试执行以下操作删除az,AZ和0-9以外的所有内容: 如果字母数字的定义包括外语字母和过时的脚本,则您将需要使用Unicode字符类。 尝试以下操作仅保留A

  • 问题内容: 为什么我返回的是JavaScript函数中的布尔变量,为什么在调用函数中将其检测为字符串,但是如果我返回布尔文字,则调用函数会将其检测为布尔值? 因此,例如: 问题答案: 您无需声明状态变量。 因此,全局一个()被覆盖。 但是,[HTML5规范]将该属性定义为DOMString: 因此,它具有一个设置器(公开的或内部的),用于存储字符串化的值。 要解决此问题,只需使用语句声明您的局部变

  • 问题内容: 我在这里想念什么吗? 为什么 不返回一个字符串? 我想将数字四舍五入为2个十进制数字。 问题答案: 它之所以返回一个字符串,是因为在二进制浮点系统中,0.1及其幂(用于显示十进制小数)不能表示(至少不能完全准确)。 例如,0.1确实是0.1000000000000000055511151231257827021181583404541015625,而0.01确实是0.010000000

  • 问题内容: 我在返回查询时遇到了几个问题。 在这里,我想做的是: 我在不同的帖子上看到了回调函数,但是它不适用于我想做的事情。 问题答案: 我在不同的帖子上看到了回调函数,但是它不适用于我想做的事情。 是的,您只需要更改对代码的思考方式即可。与其编写,不如编写一个名为的函数: 然后,而不是这样写: 您可以这样写: 现在,您可能会问自己,在那之后还有其他事情吗?好吧,您需要修改函数使其行为类似于和而