emscripten:在 C 中使用全局变量

emscripten: use globals in C

我的 wasm 模块的 C 源代码必须使用全局变量,因为它使用的代码对于执行此操作的服务器来说是通用的。但我得到:

Uncaught (in promise) TypeError: WebAssembly.instantiate(): Import #2 module="GOT.mem" error: module is not an object or function

当我尝试使用全局时。这是代码...

daft.html:

<html>
 <head>
  <meta charset=utf-8 http-equiv="Content-Language" content="en"/>
  <script src="daft.js"></script>
 </head>
</html>

daft.js:

const heap0 = new Uint8Array(mem.buffer, 0);

function squawk(cbuf,clen) {
  var s = new Uint8Array(heap0, cbuf, clen);
  let string = '';
  for (let i = 0; i < clen; i++) {
    string += String.fromCharCode(s[i]);
  }
  console.log("Squawk: "+string);
}

var imports = {
  env: {
    'memory': mem,
    'squawk': squawk,
    '__memory_base': 0,
  }
}

async function init() {
  wa = await WebAssembly.instantiateStreaming( fetch("./daft.wasm"), imports );
  wa.instance.exports.wam();
}

init();

daft.c:

#include <string.h>                    
                                       
char m[] = "Hello again. ";            
                                       
extern void squawk(const char *, int); 
                                       
void wam() {                           
  char * msg = (char *) 0;             
  strcpy(msg, "Hello from C!");        
  squawk(msg, 13);                     
}                                      
                                       
//void sorgenkind() { squawk(m, 13); }       

我是这样编译的:

emcc -s ERROR_ON_UNDEFINED_SYMBOLS=0 -s WASM=1 -s SIDE_MODULE -Os -s EXPORTED_FUNCTIONS=_wam --no-entry -o daft.wasm daft.c

因此上面的代码可以工作并打印“Hello from C!”在控制台上。但是如果我取消注释 sorgenkind 就会发生错误。

我尝试过类似的事情:

var imports = {
  GOT: { mem: blah blah blah},
  ...

但我试过的都没有任何效果。

有趣的是,全局整数不会引发问题。似乎一个字符串是最小的。也许这只是因为全局 int 被优化掉了,这个字符串显然也是如此,如果 sorgenkind 被注释掉。

我该怎么办?

我没有安装这个软件,但似乎你必须删除 -s SIDE_MODULE 标志,而不是 -o daft.wasm 使用 -o daft.html。根据 this,扩展名 .wasm 仅生成 .wasm 文件(与使用 -s STANDALONE_WASM 时一样)。但是你会需要更多。

问题是此时 WebAssembly 需要 JavaScript 胶水代码来“让它工作”。当您使用 -o draf.html 时,您将获得 .html.js.wasm 文件(请注意不要覆盖您的某些文件)。在您的情况下,这是一个非常简单的示例 linking error. Check this

简而言之,您应该只使用这个 emcc daft.c -s WASM=1 -o daft.html