Emscripten 中 ccall 和 cwarp 函数的用途是什么?

What is the purpose of ccall and cwarp functions in Emscripten?

我正在按照 Emscripten 文档 here 中的说明进行操作,并且我想用最少的示例进行练习。我的最终目标是创建一个 C++ 库,将其编译为单个 wasm 二进制文件,然后在纯前端 Web 应用程序中使用这些编译后的方法。

我不明白当您可以直接从“模块”实例化它们时,使用“ccall”调用 C++ 方法的目的是什么。例如,我可以使用 Module._doubleNumber(9);,它比 Module.ccall('doubleNumber','number', ['number'], [9]);.

更短

调用一个或另一个有什么区别?

完整代码如下:

extern "C" {
    int doubleNumber( int x ) {
        int res = 2*x;
        return res;
    }
}

编译为

emcc main.cpp -o main.js -sEXPORTED_FUNCTIONS=_doubleNumber -sEXPORTED_RUNTIME_METHODS=ccall

我正在使用一个简单的 html 文档来测试结果:

<html>
<head>
    <meta charset="utf-8">
    <title>WASM Demo</title>
</head>
<body>
    <script type="text/javascript" src="main.js"></script>   
    <script type="text/javascript">
        Module.ccall('doubleNumber','number', ['number'], [9]); // 18
        Module._doubleNumber(9); // 18
    </script> 
</body>
</html>

这么小的例子没有区别。大项目可能会有问题。

  1. 不太重要。 Module.ccall 可以使用参数 async=true 执行异步调用,而对导出函数的调用 Module._doubleNumber 始终是同步的。
  2. 更重要。在更高的优化级别(-O2 及以上),闭包编译器运行并缩小(更改)函数名称。 _doubleNumber 的缩小名称将更改为另一个名称,通常是不可预测的名称,并且 Module._doubleNumber 将是未定义的。
  3. -sEXPORTED_FUNCTIONS=_doubleNumber 防止名称缩小,可用于小型 C 库。一个大的 C 库将需要 EXPORTED_FUNCTIONS 中列出的大量项目,您应该考虑有限的命令行长度。