This post is part of a WebAssembly series focused on WASM and C++. The goal is to gain a thorough understanding of how WebAssembly works, how to use it as a compilation target for C++ code and hopefully have fun along the way. So, stick with me for this exciting journey.
Wherever mentioned, working WASM examples will be embedded directly on the page. If your browser supports it, you should be able to see them running.
That’s it! If your application is doing most of the work on WASM side and the API that it exposes is simple then this might be sufficient but in reality it rarely will be. We need to learn how to exchange strings and structured data.
Decoding WASM strings
First step will be to create a very simple WASM module that will return a static string:
If I call
to WASM module memory.
Here’s the console:
Using this pointer and a handle to WASM module’s memory
wasm.instance.exports.memory), the string has to be recreated on the
this is the reason for
str_len function which I implemented in C++ as well
(I can’t use
strlen since I’m still operating in standalone mode without
C/C++ standard library).
Here’s the console screenshot:
But… there’s a problem. I can’t just randomly write some data wherever I
want into WASM memory. Should I have access to
malloc and some sorts of heap
management facilities, that would be simple since I could just ask WASM module
to allocate memory for me that I could use. In standalone mode, it’s not that easy.
The workaround, useful for the sake of this contrived example is to explicitly allocate more memory for WASM module:
This is described on the Memory.grow page.
It’s becoming quite apparent I hope, that in the long run, this approach won’t scale and might be applicable only to a narrow specific use cases. Despite that, let’s continue.
What about structured data, like
structs passed between C++ and JS?
In short, the same principles apply as for strings. Whatever is returned
The invocation of
it doesn’t matter if you’re returning by value or by pointer explicitly.
makePair returns a pointer to a fragment of WASM memory representing a
handle it explicitly or assume its internal layout. To convert it to
You can find the discussed example code in a github repository created for the purpose of this post.
Passing structured data between JS and C++ requires serialisation. Something like a protocol buffer, JSON or msgpack. To have that working the facilities that standard C++ library provides are really a must. Therefore, in future instalments of this series, I’m gonna focus on details how to use it and how to instrument an integration layer between two environments.