Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass a string to C code compiled with emscripten for WebAssembly

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

like image 459
ElCapitaine Avatar asked Oct 18 '17 16:10

ElCapitaine


People also ask

Can C compile to Wasm?

When you've written a new code module in a language like C/C++, you can compile it into WebAssembly using a tool like Emscripten.

Can GCC compile to WebAssembly?

Once GCC supports '--target=[WebAssembly]', it can then be ported so that it can itself be compiled for/on a WebAssembly system (GCC native build), and then run inside a WebAssembly "machine" (web browser). >

Can you use C with JavaScript?

It is possible to implement a C API in JavaScript! This is the approach used in many of Emscripten's libraries, like SDL1 and OpenGL. You can use it to write your own APIs to call from C/C++.


1 Answers

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.

like image 173
ElCapitaine Avatar answered Nov 14 '22 21:11

ElCapitaine