Search code examples
javascriptc++webassemblyemscripten

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


I'm following the instructions from the Emscripten documentation here, and I want to practice with minimal examples. My final goal is to create a C++ library, compile it to a single wasm binary file and then use these compiled methods in pure-frontend web application.

I do not understand what is the purpose of calling C++ methods with "ccall" when you can just instatiate them directly from "Module". For example, I can use Module._doubleNumber(9);, which is shorter than Module.ccall('doubleNumber','number', ['number'], [9]);.

Whats the difference between calling one or another?

Here is the complete code:

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

Compiled with

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

I'm using a simple html document to test results:

<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>

Solution

  • There is no difference in such the tiny example. There might be issues in big projects.

    1. Less important. Module.ccall can perform async call with the parameter async=true, whereas call to the exported function Module._doubleNumber is always sync.
    2. More important. At higher optimisation levels (-O2 and above), the closure compiler runs and minifies (changes) function names. A minified name for _doubleNumber will be changed to another name, usually unpredictable one, and Module._doubleNumber will be undefined.
    3. -sEXPORTED_FUNCTIONS=_doubleNumber prevents name minifying and can be used for small C libraries. A big C library would require a ton of items listed in EXPORTED_FUNCTIONS, and you shall take into account the limited command line length.