getting data back to javascript from a webassembly function.

48 views
Skip to first unread message

Shawn Riordan

unread,
Feb 20, 2020, 11:44:55 PM2/20/20
to emscripten-discuss
I am new at this, so don't laugh.

I am able to make C/C++ functions that javascript can call.  When the parameters are out only.

Can I make them return parameters?

Lets say I want to return a point.  Two values, x and y.
In C/C++ I would make my function look like:

void getFoo( float &x, float &y);

and have the implementation fill in the values for those two references. The caller could then read the values out of the variables they passed in.

How do I do a similar thing with WebAssembly and javascript?

At the moment, I am implementing the solution by having the WebAssembly code call back to javascript with the answer.  But that feels wrong in many ways.

Also, allocating a shared buffer to write to, feels wrong in this case.  Since it happens on mouse move and all those memory allocations seem wasteful.

What is the right way to do this?

Shachar Langbeheim

unread,
Feb 21, 2020, 1:58:03 AM2/21/20
to emscripten-discuss
You need to use embind to define the return type and the function.
https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html  

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/emscripten-discuss/73244098-e837-46e7-892e-d39346405347%40googlegroups.com.

Alon Zakai

unread,
Feb 21, 2020, 8:46:54 PM2/21/20
to emscripte...@googlegroups.com
I think there are multiple ways to do this. Embind is one option as Shachar suggested. Another is to use a little shared buffer as you mentioned - to avoid memory allocations, you can just allocate one such singleton buffer at the beginning of the program, and keep reusing it for all calls to that function. That could be very efficient.

--

Floh

unread,
Feb 24, 2020, 5:03:40 AM2/24/20
to emscripten-discuss
> At the moment, I am implementing the solution by having the WebAssembly code call back to javascript with the answer.  But that feels wrong in many ways.

This is exactly what I'm doing in my C code (no fancy "embind", but I like it that way because there's less "magic" involved").

I basically just use EM_JS() for JS functions that need to be called from C, and EMSCRIPTEN_KEEPALIVE for C functions that need to be called from JS. If I need to return complex data (anything else than just an integer return value), I call a C function from JS.

For getting "data blobs" across, I pass pointers as integers to the JS side, and access the various global HEAP views from JS code, if I need to pass blob data from JS back to C, I usually pass a pointer and size to JS, and copy the data there from JS by via the HEAP views (it's also possible to call C's malloc from JS, but I haven't done that so far).

Floh

unread,
Feb 24, 2020, 5:12:14 AM2/24/20
to emscripten-discuss
PS: here is a "real-world-example" of what I wrote above in a WIP WebGPU wrapper. Most initialization functions in WebGPU are asynchronous, and it's much easier to do this stuff in JS than C, and when all the promises have resolved, a C function is called (emsc_device_ready()) with the multiple results (handles for the WebGPU device, swapchain and the swapchain image format).


Cheers,
-Floh.
Reply all
Reply to author
Forward
0 new messages