Nqueens using Webassembly
In the last post, we discussed the 8 queens problem and showed some C++ code. But, when we wanted to use it in Web (without any server side interaction), we had to give away our source code and also had to rewrite everything in Javascript. Is there a way to hide the code and also reuse the C++ code, you ask? Yes, there is. It is called Webassembly. I will show you how.
Webassembly basics
Thankfully, there is a webassembly compiler toolchain called Emscripten that can easily compile your C/C++ code. For our use case, we are going to compile a single program. So, we could simply call the emcc
compiler instead of g++
. If you have a bigger project that uses something like CMake, emcc can still compile it without any issues.
To avoid the hassle of setting up my own build environment, I went the docker route. If you are not familiar with docker, I will cover it in another post. For now, think of it as a virtual machine that comes with all the dependencies needed to do a specific task (in our case, compile programs with emscripten toolchain).
The only requirement to interface your native code with Javascript is the need for pure C functions. This is because C++ compilers mangle the symbol names. So, I have modified my C++ nqueens code to add C interfaces for the functions we need to call from Webassembly. In this case, there is a Create
function that solves the Nqueens problem. There is a GetNumSolutions
function that returns the number of possible solutions and a GetNextSolution
function that returns the array of results in sequential order every time it is called. I have marked these three functions as C by wrapping them around extern "C"
. Finally, I have added a tag EMSCRIPTEN_KEEPALIVE
for these functions to let emscripten know that these functions should not be optimized out since they are not called. Note how we don’t have a main function.
How to compile this program?
Emscripten website has excellent documentation. You can consult that site for more details. For our case, I used the following command on my Windows machine to compile the C++ code to Webassembly.
This command emits out two files: a.out.js
and a.out.wasm
. The Javascript file is an auto-generated wrapper to access our exposed webassembly functions. a.out.wasm
is the binary file containing our compiled code - much like an object file. Our implementation is completely hidden. Great!
How to access the Webassembly code from Javascript?
Again, Emscripten covers a lot of this. I also consulted this Google Developer page for my reference. It is a great read! I recommend going through it once. Here is the javascript code I had to write to interface with Webassembly. Note, how we use number
for pointers. You can find more information about different types that are available here.
Live demo
How about a live demo? Of course. I am using the same frontend code as last time. But, in the new version, I am using the Webassembly interface described above. This means, we are actually running C++ code in the browser. Hurray! Hit me up if you have any questions.