跟我一起从零开始学习WebAssembly(七)、常见问题之为什么C/C++源代码编译为javascript后,在js中找不到函数

参考来源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上一样。

注意

  • 所有没有使用EXPORTED_FUNCTIONSEMSCRIPTEN_KEEPALIVE保存的函数都可能被删除。为了确保使用这些方法,你需要使用其中的一种或两种来保持你想要的接口。
  • 导出的函数需要是C函数(以避免被C++修改名称)。
  • 如果你想一直跟踪显式导出的函数且这些导出不会被改变,则使用EMSCRIPTEN_KEEPALIVE修饰会很有用。它不一定适合从其他库导出函数 - 例如,修饰且重新编译C标准库的源代码不是一个好主意。如果以多种方式编译相同的源并更改导出的内容,那么使用命令行管理导出更容易。
  • 运行emcc命令-s LINKABLE = 1将禁用链接时优化和消除无效代码。建议不要这样做,因为它会使代码变大和减少优化。

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SunkingYang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值