Reputation: 1772
I've been pulling out my hair and am hoping someone can help as I have been unable to find an example of what I need to do and am in link error hell. :-)
I'm trying to get a C module working, with which I can share memory and call back into JS. The tricky bit is this is going into an AudioWorklet, so I cannot just compile to js and get the module plumbing from emscripten. In order to load it, I must manually instantiate. Binary data is fetched in the main file, sent to the worklet as a message, and then compiled and instantiated there. This is working fine when I compile as a side module, and I can access my dummy C function (multiply) ok. compile line is:
emcc multiply.c -O2 -s WASM=1 -s SIDE_MODULE=2 -s EXPORTED_FUNCTIONS=['_multiply'] -o multiply.wasm
Instantiation in the worklet looks like this:
console.log("initWasm()");
// setup linear memory for the WASM module
const importObject = {
'env': {
__memory_base: 0,
__table_base: 0,
memory: new WebAssembly.Memory({initial: 10}),
table: new WebAssembly.Table({initial: 0, element: 'anyfunc'})
}
}
this.module = await WebAssembly.compile(data.arrayBuffer);
this.instance = await WebAssembly.instantiate(this.module, importObject);
All good so far. But attempting to write memory such that C can access is it where I'm stuck. I have found this example (adapted a bit)
var buf = Module._malloc(this._events.length * this._events.BYTES_PER_ELEMENT);
Module.module.HEAPU8.set(this._events, buf);
But of course I don't have "Module" because it was a manual instantiation of a side module. So I tried various variants on:
emcc multiply.c -O2 -s WASM=1 -s SIDE_MODULE=2 -s EXPORTED_FUNCTIONS=['_malloc','_multiply'] -s EXPORTED_RUNTIME_METHODS=['cwrap','ccall','UTF8ToString'] -o multiply.wasm
With this in my js
var buf = this.module._malloc(this._events.length * this._events.BYTES_PER_ELEMENT);
this.module.HEAPU8.set(this._events, buf);
But I am not getting a malloc. I tried adding this to init above to check on it, but there is no malloc.
console.log(" this.module._malloc:", this.module._malloc);
console.log(" this.module.malloc:", this.module.malloc);
console.log(" this.instance.exports._malloc:", this.instance.exports._malloc);
console.log(" this.instance.exports.malloc:", this.instance.exports.malloc);
My C file looks like this:
#include <stdlib.h>
#include <stdio.h>
include "emscripten.h"
EMSCRIPTEN_KEEPALIVE
// a function to compile as wasm
float multiply(float arg1, float arg2){ return arg1 * arg2; }
If anyone knows how to get this to work, that would be lovely. Or any suggestions on how to figure it out.
thanks!
Upvotes: 0
Views: 1180
Reputation: 3022
You want to be using the STANDALONE_WASM mode, not SIDE_MODULE. See https://v8.dev/blog/emscripten-standalone-wasm.
Standalone mode can be enabled either explictly via -sSTANDALONE_WASM
or implicitly by specifying an output name that ends in .wasm
. e.g. emcc hello.c -o hello.wasm
.
Upvotes: 1