emscripten:在 C 中使用全局变量

Posted

技术标签:

【中文标题】emscripten:在 C 中使用全局变量【英文标题】:emscripten: use globals in C 【发布时间】:2021-10-08 16:54:38 【问题描述】:

我的 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 被注释掉,这个字符串也是如此。

我该怎么办?

【问题讨论】:

【参考方案1】:

我没有安装此软件,但您似乎必须删除-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。查看this 以获得一个非常简单的示例。

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

【讨论】:

嗯,这就是我开始的地方,我无意使用所有的胶水,但是通过让它编写 JS 并阅读它,我发现我应该尝试从C、不导入。当我再次有时间时,我想这会告诉我如何让它发挥作用。

以上是关于emscripten:在 C 中使用全局变量的主要内容,如果未能解决你的问题,请参考以下文章

仅在目标 C 中本地更新全局变量值

emscripten链接全局命名符号多重定义

C语言全局变量(c文件和h文件中的全局变量静态全局变量)使用注意事项

C语言全局变量(c文件和h文件中的全局变量静态全局变量)使用注意事项

带有 SDL 音频的 Emscripten 工作模型

C语言之变量作用域