Genie is here to save us tons of work

Cross platform mobile apps development with C++

Made easy with Djinni

Hello World! Thank you for reading my first ever Medium post! In this year of the Dog I am blessed to have the privilege to work for Netvirta — an uber cool company that works with 3D body scanning technologies.

We utilise a lot of C++ in our applications in order to tap into every bit of performance that the mobile devices can handle. It was an uncharted territory for me as I never have to touched C++ to create my applications before. Android Studio has made it easy to setup projects with NDK enabled. Just follow this guide and we will be creating a simple application that prints “Hello World” to the screen from C++ to Java, with just a click of a button.

So in this post, I am going to create a very rudimentary calculator on Android and iOS with a shared C++ code.

In order to make C++ visible to Java codes, we have to create an interface called the Java Native Interface (JNI). So this is how it works on Android.

  • Import the library statically in our Java class.
  • Create a Java native method
  • On the C++ side, create a cpp file and a method that refers to the native method with that was created during step #2. The method has to be named correctly, including the name of the Java package and class. This method can have parameters and returns Java classes such as jobject, jstring, jint or whatever that starts with the letter j. We can return void as well.
  • Then we insert whatever code with in the C++ file. And then call the method from the Java side, and the C++ code will run and returns the stuffs that we programmed in the C++ code that we have created in step #3.

So that’s how to call a “Hello World” from the Java side. However, it is a real pain in the butt to write all these codes. It is a long, tedious process plus they are very error prone even when we are writing a very simple method that returns a String. What if we need a more complex interfaces with things like objects and listeners? Wouldn’t it be good if we don’t have to write a single line of JNI calls anymore?

The solution is Djinni! It stands for “Dropbox’s JNI”. In the video where they first announced Djinni in the 2014 C++ conference. The dropbox team wanted to develop most of the features in C++ and shared them between both Android and iOS. In order to make the process less painful. They have created a tool that helps them generates all the JNI calls, Objective C++ codes and C++ for very easy cross platform development. There is even an experimental branch where it can be used to link up with Python too!

Let’s create the App!

Now that I got those introductions out of the way, let’s get our hands dirty and do some code!

To show how easy to use Djinni to make life easier for the developers, I am going to show how to create a very simple calculator in C++ and generates all the codes that we don’t have to write manually anymore. There are some setup in the beginning of the project. But once we get it done, the subsequent steps will be as smooth as butter!

The first step is to create a project folder in the terminal. In my case I’ll do a mkdir CrossPlatformCalculator && cd CrossPlatformCalculator

Next is to do a git init in the folder we created. Next is to make the Djinni repository as a submodule.

git submodule add https://github.com/dropbox/djinni.git

Then we’ll create a calculator.djinni file at the root of the project. In the file we will add in a very basic function of summation in calculator.

Tips: The comments will appear in the generated C++/Java/Objective C files

Djinni file is written in it’s own interface description language (IDL) to interface between the C++ codes and Java/Objective C. We can see that there are two methods that I have created there. A create() method for initialising the object, and summation(number1: i32, number2: i32) i32 the method that will be generated across different languages.

So now, let’s generate our C++, Java, and ObjC files! In the terminal, run the commands below. If we are the first time running it, it will take a few minutes to download dependencies that Djinni needed.

djinni/src/run \
--java-out generated/java/com/example/yourcompany \
--java-package com.example.yourcompany \
--ident-java-field mFooBar \
--cpp-out generated/cpp \
--cpp-namespace calculator \
--jni-out generated/jni \
--ident-jni-class NativeFooBar \
--ident-jni-file NativeFooBar \
--objc-out generated/objc \
--objc-type-prefix CL \
--objcpp-out generated/objcpp \
--idl calculator.djinni

Here is a brief explanation for each of the commands:

  1. djinni/src/run is the code generator program.
  2. --java-out is where we put our generated java files.
  3. --java-package is where we put our company package name.
  4. --ident-java-field determines how our fields going to look like. mFooBar means it will have a m prefix. → mNumber
  5. --cpp-out is where we put our generated C++ files.
  6. --cpp-namespace is the namespace for our C++ files.
  7. --jni-out is where we put our JNIs
  8. --objc-out is where we put our Objective C files.
  9. --objc-type-prefix is where we put our prefix in the Objective C class.
  10. --objcpp-out is where we put our Objective C++ files
  11. --idl is the .djinni file that we wrote earlier.

And so here they are. As an optional step, we can cd into the generated folders to look at all the files that are generated by Djinni! Imagine that we are the one that are required to write them by hand without Djinni. *Shudders*`

Let’s create a Command Line Application!

Setup

  • In the root of the project, make a src/cpp folder.
  • Copy the generated calculator.cpp file into the newly created cpp folder. cp generated/cpp/calculator.cpp src/cpp/calculator.cpp
  • Create a calculator_impl.hpp that extend the calculator.cpp methods created by the Djinni.
  • Create a calculator_impl.cpp that contains all the running codes.
  • Next we are going to create the main.cpp in the src/cpp/ folder.

Run the command

  • g++ calculator.cpp calculator_impl.hpp calculator_impl.cpp main.cpp . An a.out file will be created.
  • Run ./a.out. And the summation will be printed on the screen.

So I’m going to end the post here before it gets too long. And I’ll write Part 2 where I’ll use the generated codes in our Android project. And then Part 3 for the iOS version. I hope we all learn something out of this!

You can take a look the completed code in my GitHub repository here https://github.com/LiewJunTung/DjinniPractice

Cross platform mobile apps development with C++ (Made easy by Djinni)

  • Part I
  • Part II — Implementing C++ in Android
  • Part III — Implementing C++ in iOS

References

P.S. We are hiring

--

--

--

Mobile developer; Netvirta; Android; Flutter; Gradle; Kotlin

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Angular on Azure — Part I

A Coders Diary | How I use Trello for improving my workflow!

How to Mount a Share Folder in all my VirtualBox Virtual Machines

Preventing Hero Culture In Software Teams

Magento 2 migration: Data migration from Magento 1 to Magento 2

‘Functional’ Swift #1: Looking for Patterns

SOLID Android analytics with RxJava2

Become confident in Webpack

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
JT Liew

JT Liew

Mobile developer; Netvirta; Android; Flutter; Gradle; Kotlin

More from Medium

KMP, iOS Developers and Production

Kotlin Multiplatform Mobile (KMM) Part 1: Introduction

Create a Simple Counter App : Kotlin Basics

TDD — Part III, Hilt and Robolectric (Android)