IT.技术分享

跟我一起从零开始学习WebAssembly(七)、常见问题之为什

2019-07-09  本文已影响0人  5de9e117f2fe

参考来源Why do functions in my C/C++ source code vanish when I compile to JavaScript, and/or I get No functions to process?

Emscripten执行无效代码清除编译代码中未调用的函数。虽然这确实最小化了代码大小,但它可能删除了你打算本来要自己调用的函数(在编译代码之外)。

要确保在通用JavaScript中仍可以能够调用C函数,必须使用emcc命令行将其添加到EXPORTED_FUNCTIONS中。例如,要防止函数my_func()main()被删除或者重命名,请运行emcc

emcc -s“EXPORTED_FUNCTIONS = ['_main','_my_func']”......

注意
如果你有一个main()函数,_main应该在导出列表中,就像在那个例子中一样。否则,它将作为无效代码被删除;默认情况下,没有特殊的逻辑来保持main()有效。

注意
EXPORTED_FUNCTIONS影响到JavaScript的编译。如果首先编译为对象文件,然后将对象编译为JavaScript,则需要在第二个命令上使用该选项。
如:

emcc -o ..... -s“EXPORTED_FUNCTIONS = ['_main','_my_func']”......

如果你的函数用于其他函数,LLVM可能会内联它,它不会在JavaScript中显示为唯一函数。通过使用EMSCRIPTEN_KEEPALIVE定义函数来防止内联:

void EMSCRIPTEN_KEEPALIVE yourCfunc(){..}

EMSCRIPTEN_KEEPALIVE也导出该函数,就像它在EXPORTED_FUNCTIONS上一样。

注意

一个可能会引起丢失代码的可能是.a文件的链接不正确。 .a文件仅链接命令行上以前文件所需的内部对象文件,因此文件的顺序很重要,这可能会令人惊讶。如果要链接.a文件,请确保它们位于文件列表的末尾,并且它们之间的顺序正确。或者,只需在项目中使用.so文件。

提示
使用EMCC_DEBUG = 1为环境设置编译(在Linux上EMCC_DEBUG = 1 emcc ...,在Windows上设置EMMCC_DEBUG = 1)可能很有用。这将拆分编译步骤并将它们保存在/ tmp / emscripten_temp中。然后,您可以看到代码消失的阶段(您将需要在bitcode阶段上执行llvm-dis来读取它们,或者llvm-nm等)。

上一篇 下一篇

猜你喜欢

热点阅读