Extending HTML5 Mobile Apps with C++

With the MoSync SDK you are not restricted to just coding in HTML5/JavaScript. You can use the Wormhole communication bridge to talk to C/C++ from JavaScript — really useful when you want to extend your HTML5/JavaScript application with custom code written in C++.

Invoke C++ Code from JavaScript

The following example code is based on the HTML5/JS/C++ Hybrid Project Template. This template illustrates how to invoke custom C++ code from JavaScript. The UI has buttons for making the device vibrate and beep.

To create a project based on this template, launch MoSync SDK, and create an app in the Eclipse-based IDE, using the HTML5/JS/C++ Hybrid Project template. Then you will get the source code discussed below.

The template app uses the Wormhole C++ library (classes HybridMoblet and MessageStream) and the JavaScript libraries included in the file wormhole.js (all included with the application template).

Sending String Messages

It is good to know that two message formats are supported by Wormhole: JSON messages and String stream messages. The example we discuss here uses String streams.

String streams are a performant way of sending messages from JavaScript to C++. This method is generally faster than JSON messages (on some platforms 20x faster). Parsing on the C++ side is very efficient, and streams of string messages are concatenated before passed to C++. This makes sending a large number of small messages efficient.

The JavaScript function mosync.bridge.send() is used to send string messages to C++:

mosync.bridge.send(messageArray, callbackFunction)

This function takes two parameters. The first parameter "messageArray" is an array of strings.These values will be sent to C++. By convention, the protocol for sending custom messages is based on the first element in the array being the string "Custom", and the second element being the name ("action") of the message, like "Beep". Then follows any parameters. (See example below.)

The second parameter "callbackFunction" is an optional function that you can use to send back a result value from C++ to JavaScript. The communication mechanism is asynchronous, which is why a callback function is used to pass the result back from C++ to JavaScript.

Here is an example of a JavaScript call that sends a custom message C++ to make the device vibrate (here we do not need to use any callback function):

mosync.bridge.send(["Custom", "Vibrate", "500"]);

This JavaScript code is found in file index.html in the generated template application.

In the corresponding implementation in C++, the message "Vibrate" is first registered in the constructor of the the application's Moblet, in class MyMoblet. A Moblet is the main object in a MoSync application, and the constructor is a good place to declare message to method bindings.

The call to message.getNext() retrives a char pointer (char*) to the next parameter in the message stream, in this case the duration time ("500"). If there are no more messages, NULL is returned.

Note that when a message handling method is called, the first two elements of the original string array sent from JavaScript have been "consumed" by the message handling framework, and the first call to message.getNext() will therefore return a pointer to the first parameter in our message, the value "500".

You can also have messages with no parameters. The "Beep" message is an example of this. Here is the call made from JavaScript:

Then define the getScreenSize method. Here we create a script that invokes the JavaScript function mosync.bridge.reply() with the callbackId of the message and the result parameters (this will call the function specified above, in the call to mosync.bridge.send):

The JavaScript function mosync.bridge.reply() always takes the callbackId as the first argument. You can then supply a variable number of arguments (zero to many) that will be passed to the callback function in JavaScript.

Under The Hood

If you wish to dig deeper, you can explore the MoSync source code at GitHub, and you can also take a look at the example program WebViewGeoLocation, which is a low-level example that does not use the Wormhole library. Note that wormhole.js is a generated file, made up of several JavaScript source files (which means it is not found in the GitHub repository).