如何从C/C ++访问WebAssembly线性内存 [英] How to access WebAssembly linear memory from C/C++

查看:64
本文介绍了如何从C/C ++访问WebAssembly线性内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个小型C程序,旨在通过 emcc 编译为wasm并在Web浏览器中运行.因为wasm导出的函数只能接受简单的数字值作为参数输入和返回值,所以我需要在JavaScript API和已编译的WebAssembly代码之间共享内存,以便访问更复杂的数据类型,例如字符串或 char 数组.问题是我一生无法解决如何访问 WebAssembly线性内存在我的C程序内部.

I'm writing a small C program intended to be compiled to wasm w/ emcc and run in a web browser. Because wasm exported functions can only accept simple number values as parameter inputs and return values, I need to share memory between the JavaScript API and the compiled WebAssembly code in order to access more complex data types like strings or char arrays. The problem is that I can't for the life of me figure out how to access WebAssembly linear memory from inside of my C program.

我的最终目标是能够读取在C程序内部用JavaScript初始化的字符串,然后还可以在Web浏览器的JavaScript代码中读取在C程序中修改/初始化的字符串.

My ultimate goal is to be able to read strings initialized in JavaScript inside of my C program, and then also read strings that are modified/initialized in my C program back in the web browser's JavaScript code.

这是我要执行的操作的基本示例:

Here is a basic example of what I'm trying to do:

main.js

const importObject = {
  'env': {
    'memoryBase': 0,
    'tableBase': 0,
    'memory': new WebAssembly.Memory({initial: 256}),
    'table': new WebAssembly.Table({initial: 0, element: 'anyfunc'})
  }
}

// using the fetchAndInstantiate util function from
// https://github.com/mdn/webassembly-examples/blob/master/wasm-utils.js
fetchAndInstantiate('example.wasm', importObject).then(instance => {

      // call the compiled webassembly main function
      instance.exports._main()
      console.log(importObject.env.memory)
})

example.c

example.c

int main() {
    // somehow access importObject.env.memory 
    // so that I can write a string to it
    return 0;
}

此问题但是,我仍然不了解如何在我的C代码中从WebAssembly内存缓冲区读取/写入.

This question gets me part of the way there, however, I still don't understand how to read/write from the WebAssembly memory buffer in my C code.

推荐答案

您需要做的是在WebAssembly模块中传达C/JavaScript代码都可读取/写入的位置.

What you need to do is communicate a location within the WebAssembly module that both the C and JavaScript code read / write to.

这是一个简单的示例,为数组中的每个元素添加了一个数字.这是C代码:

Here's a simple example that adds a number to each element in array. This is the C code:

const int SIZE = 10;
int data[SIZE];

void add(int value) { 
  for (int i=0; i<SIZE; i++) {
    data[i] = data[i] + value;
  }
}

int* getData() {
  return &data[0];
}

上面的代码中重要的是 int * getData()函数,该函数返回对 data 数组开头的引用.当编译为WebAssembly时,它将返回一个整数,该整数是模块线性内存中 data 数组的位置.

The important thing in the above code is the int* getData() function, which returns a reference to the start of the data array. When compiled to WebAssembly, this will return an integer which is the location of the data array within the modules linear memory.

以下是使用方法的示例:

Here's an example of how to use it:

var wasmModule = new WebAssembly.Module(wasmCode);
var wasmInstance = new WebAssembly.Instance(wasmModule, wasmImports);

// obtain the offset to the array
var offset = wasmInstance.exports.getData();

// create a view on the memory that points to this array
var linearMemory = new Uint32Array(wasmInstance.exports.memory.buffer, offset, 10);

// populate with some data
for (var i = 0; i < linearMemory.length; i++) {
  linearMemory[i] = i;
}

// mutate the array within the WebAssembly module
wasmInstance.exports.add(10);

// log the results
for (var i = 0; i < linearMemory.length; i++) {
  log(linearMemory[i]);
}

您可以在 WASM小提琴中看到完整的示例.

You can see the complete example in this WASM fiddle.

这篇关于如何从C/C ++访问WebAssembly线性内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆