6

I've been looking a the WebAssembly website and tutorials and I feel a bit lost.

I have the following C code :

void EMSCRIPTEN_KEEPALIVE hello(char * value){
    printf("%s\n", value);
}

I compiled it with (I'm also not sure this part is the best way to go) :

emcc demo.c -s WASM=1 -s NO_EXIT_RUNTIME=1 -o demo.js

From what I understand I can now use the demo.js glue code in my javascript class and call the method that way :

...
<script src="demo.js"></script>
<script>
    function hello(){        
        // Get the value 
        var value = document.getElementById("sample");
        _hello(value.innerHTML);
    }
</script>
...

What I see being printed in the console when I call the method is :

(null)

Is there something I'm missing to pass a string value to C code compiled with WebAssembly ?

Thanks a lot

ElCapitaine
  • 830
  • 1
  • 11
  • 24
  • 1
    What are `hello` and `_stringify` and where do you call them? – Bergi Oct 18 '17 at 16:45
  • that's a typo, it should be _hello(value.innerHTML), I edited the question, sorry for that – ElCapitaine Oct 18 '17 at 17:01
  • Note that you have to export functions to be able to call them from js: `emcc demo.c -01 -s EXPORTED_FUNCTIONS="['_main', '_hello'] -o demo.js"` Also don't feel bad about struggling, this is all new and under heavy development and the docs are necessarily incomplete and out of date. – Jared Smith Oct 18 '17 at 17:08
  • But the thing is that is I replace printf("%s\n", value); and hardcode with printf("Hello!\n"); I can clearly see the "Hello" being printed in the console. It also works if I pass integer values. So it's really an issue with strings. – ElCapitaine Oct 18 '17 at 17:22
  • 2
    Possible duplicate of [How can I return a JavaScript string from a WebAssembly function](https://stackoverflow.com/questions/41353389/how-can-i-return-a-javascript-string-from-a-webassembly-function) – JF Bastien Oct 18 '17 at 17:58

1 Answers1

16

I actually found an answer to my question. I simply had to use the functions that Emscripten builds automatically within the 'Glue' code that's also generated when you build your C++ code to WASM.

So basically, to pass a String to C++ code compiled to WebAssembly with Emscripten you simply do it like this :

// Create a pointer using the 'Glue' method and the String value
var ptr  = allocate(intArrayFromString(myStrValue), 'i8', ALLOC_NORMAL);

// Call the method passing the pointer
val retPtr = _hello(ptr);

// Retransform back your pointer to string using 'Glue' method
var resValue = Pointer_stringify(retPtr);

// Free the memory allocated by 'allocate' 
_free(ptr);   

More complete information on Emscripten's page.

ElCapitaine
  • 830
  • 1
  • 11
  • 24
  • 4
    Thanks for the info. For those who are wondering, if you want to access those functions, you have to add them when compiling your wasm build. For example, the compiling options of emcc to get (in add of cwrap) the function allocate & intArrayFromString available in the output.js file is the following: `-s EXTRA_EXPORTED_RUNTIME_METHODS='["cwrap", "allocate", "intArrayFromString"]'` – godot Jun 19 '18 at 22:27