-2

I am working on a project that uses a pointerized version of HTML5 Canvas from C++/Wasm. I have currently an import, `void drawImageFromURL(const char *, int, int, int, int, float)` and an export, `void frame(void)`. My problem is that `drawImageFromURL`, in the resulting Wasm, is imported as `_Z16drawImageFromURLPKciiiif` and `frame` is exported as `_Z5framev`.

I am building using a shell script called `wasmc`, which uses clang (I have had only bad experiences with Emscripten), which contains the following code: ```sh #!/bin/bash clang --target=wasm32 -Wl,--export-dynamic -Wl,--no-entry -Wl,--allow-undefined -Wl,--import-memory $* --sysroot /home/linuxbrew/.linuxbrew -I/usr/include -L/usr/lib -nostdlib ``` I am using it like this: ``` $ wasmc -o main.wasm main.cpp -Oz ```

I am using Debian GNU/Linux 9 (stretch) 64-bit (copied from GNOME Settings) on a `Intel® Core™ i5-9400F CPU @ 2.90GHz × 6 ` CPU with 7.7 GiB of RAM and a Radeon RX 580 Series (POLARIS10, DRM 3.27.0, 4.19.0-5-amd64, LLVM 7.0.0) graphics card with 235.8 GB of disk space.
I am using clang version 9.0.0, installed through Linuxbrew ([Homebrew](https://brew.sh) for Linux).

I would really appreciate some help on this.
Thanks!

Here is the source code for all the files in my project:
main.cpp:

extern void drawImageFromURL(const char *url, int x, int y, int h, int w, float θ);

__attribute__((visibility("default")))
void frame() {
    static float θ = 0;
    drawImageFromURL("/gear.png", 50, 50, 100, 100, θ);
    θ += 0.01;
}

main.wasm (S-expressions generated by the VS Code WebAssembly extension):

(module
  (type $t0 (func (param i32 i32 i32 i32 i32 f32)))
  (type $t1 (func))
  (import "env" "memory" (memory $env.memory 2))
  (import "env" "_Z16drawImageFromURLPKciiiif" (func $drawImageFromURL_char_const*__int__int__int__int__float_ (type $t0)))
  (func $frame__ (type $t1)
    i32.const 1028
    i32.const 50
    i32.const 50
    i32.const 100
    i32.const 100
    i32.const 0
    f32.load offset=1024
    call $drawImageFromURL_char_const*__int__int__int__int__float_
    i32.const 0
    i32.const 0
    f32.load offset=1024
    f64.promote/f32
    f64.const 0x1.47ae147ae147bp-7 (;=0.01;)
    f64.add
    f32.demote/f64
    f32.store offset=1024)
  (table $T0 1 1 anyfunc)
  (global $g0 (mut i32) (i32.const 66576))
  (export "_Z5framev" (func $frame__))
  (data (i32.const 1024) "\00\00\00\00")
  (data (i32.const 1028) "/gear.png\00"))

index.html:

<!doctype html>

<html>
    <head>
        <title><!-- Ommitted for anonymity --></title>
    </head>
    <body>
        <canvas id="canvas"></canvas>
        <script src="app.js"></script>
    </body>
</html>

app.js:

function ptrToStr(mem, ptr, width = 'Uint8') {
    let dv = new DataView(mem.buffer);
    let str = '';
    for(let i = 0; i < strlen(mem, ptr, width); i++) {
        str += String.fromCharCode(dv['get' + width](ptr + i));
    }
    return str;
}
function strlen(mem, ptr, width = 'Uint8') {
    let dv = new DataView(mem);
    let i = 0;
    let ch = () => dv['get' + width](ptr + i);
    while(ch() != 0) {
        i++;
    }
    i++;
    return i;
}
/** @type {HTMLCanvasElement} */
let canv = document.getElementById('canvas');
fetch('main.wasm')
    .then(res => res.arrayBuffer())
    .then(arrbuf => WebAssembly.instantiate(arrbuf, {
        env: {
            memory: new WebAssembly.Memory({initial: 10}),
            _Z16drawImageFromURLPKciiiif(pUrl, iX, iY, iH, iW, fTheta) {
                let img = document.createElement('image');
                img.url = pUrl;
                img.height = iH;
                img.width = iW;
                canv.getContext('2d').drawImage(img, iX, iY);
            }
        }
    })).then(mod => main(mod));
General Grievance
  • 4,555
  • 31
  • 31
  • 45
nonagone
  • 1
  • 2
  • 2
    What exactly is the problem? That looks like mangled symbol names, which is expected behavior of C++. Symbol names must contain not only the function names, but also parameter types etc for overload resolution. That's why they are mangled like this. – walnut Jan 11 '20 at 14:16
  • The problem is that I want to have slightly more readable import/export code on the JS side. Do you know if there is any way to specifically set a symbol name for LLVM/Clang? (Ex. using something like `__attribute__((symbol_name("something")))`) – nonagone Jan 11 '20 at 15:16
  • Found the answer here: [c++ - How can i avoid name mangling?](https://stackoverflow.com/questions/524633/how-can-i-avoid-name-mangling) – nonagone Jan 11 '20 at 15:39

1 Answers1

-1

You can try the clang -Wl,--demangle option.