

Developing a mobile cross-platform library in C++ - jeopard
http://www.skyscanner.net/blogs/developing-mobile-cross-platform-library-part-2-c

======
jnbiche
Every time I think about what Android _could_ have been, my frustration
mounts. Google chose to use Java for the top layer on top of their native code
libraries (as in on top of C libraries like surface manager, opengles, openvg,
sgl, etc.). Why they chose Java instead of a language that integrates well
with C, I just don't understand. It would have made the ecosystem much more
open.

I wish they had considered just making the top layer in Luajit, as well as
exposing a C API. Luajit would have been just as efficient battery-wise as
Dalvik, and perhaps even better-performing. Best of all, people then could
have much more easily built libraries for Python, Ruby, and any other language
with good C interop.

Instead, we're left with Java. It's not a bad language, but it is very bad at
integrating with other languages and platforms.

I prefer Android to iOS, but the iOS architecture is definitely more open to
third-party platforms. Unfortunately, Apple is not so welcoming and puts up
roadblocks.

~~~
rdtsc
Yeah I think Python would have been a good choice. Something that looks like
kivy perhaps.

[http://kivy.org/#home](http://kivy.org/#home)

Java is just too popular and too average. Has enough people knowing it, works
well with an IDE, compiles (and thus hides the source better).

The apps I wrote for example, was more about the API and editing XML files.
I've used Java before but in this case it felt different, I would say easier.
Not a lot of FactoryFactoryManager type mess many stereotypically associate
with Enterprise Java back-ends. So it wasn't too bad.

Another interesting point. At one of the PyCons someone asked Guido publicly
(he was still at Google back then), why doesn't Android use Python more? And
Guido replied it was a "political decision". Moreover the tone he replied it
was betraying that he was a bit upset or annoyed at it. So I imagine there was
some internal discussion, perhaps more than one and more than once, and one
camp one and one lost.

~~~
bch
I would love it if Tcl were a first class option. W/o getting into Tcl vs. Lua
vs. Python vs. Ruby vs. Perl vs. Chicken Scheme vs... if the underlying
platform really were C, all these things would be viable options. C would have
let all these flourish.

------
rajeevk
I have written a good chuck of common code in C++ for my diagramming app "Lekh
Diagram"([http://www.avabodh.com/lekh](http://www.avabodh.com/lekh)). The
shape recognition, shape management etc all done in C++ code. The app is
available for Android and iOS.

Integrating the C++ code with Objective C is much smoother experience than the
Java in android.

As the Objective C (more precisely objective C++) is superset of C++, I can
directly call C++ code from objective C and for other way communication
(calling objective C code from C++), I had defined an C++ interface. The C++
code calls on interface only and the interface is implemented in objective C.

For Android, little more work was required. I had write wrappers code. I also
had to hit many stupid issues like local reference table overflow etc.

~~~
zbowling
Objective-C also runs on Android with Apportable. Less of a headache. :-)

~~~
jeopard
It might, but unfortunately, you can't build a library with it. It only
transforms whole apps. Apportable was investigated in the first part here
[http://www.skyscanner.net/blogs/developing-mobile-cross-
plat...](http://www.skyscanner.net/blogs/developing-mobile-cross-platform-
library-part-1-exploring)

~~~
dottrap
Not once did the article talk about the C++ ABI which is one of the most
important things a library developer needs to be aware of (as opposed to an
application developer).

The C++ ABI is unstable. You can't effectively deploy 3rd party libraries with
that either.

Android ships with multiple versions of the compiler, each one of those are
incompatible with each other's standard library. On top of that, Android ships
multiple C++ standard libraries for each compiler, all of which are not-
interoperable either. Then Android updates the compiler with each NDK drop
introducing more potential incompatibilities.

The end result is you can't deploy prebuilt C++ libraries (a prickly issue for
commercial/proprietary code) unless you can force users to use your exact
toolchain. But library writers usually can't fairly dictate those terms,
especially if the users want intermix libraries from other sources which may
use a different toolchain.

------
zbowling
Or you know you can use Apportable and write Objective-C which is entirely
cross-platform. :-) Don't have to sell your soul to C++ if you don't want too
and you don't have to deal with the NDK.

If really want to write C++, Apportable also is the only place you will get
full C++11 support (using libc++) and the same clang as iOS to make your life
easier with just a little bit of constancy.

It will seriously make your life easier (the big thing is not having to
maintain Makefiles for Android).

~~~
checker659
If you can use libc++, what's stopping me from doing the same? Why should I
use Apportable instead of just heading over to clang's website and
downloading/building/linking it myself?

~~~
zbowling
It won't work out of the box. There is actually a project in the AOSP world
that attempted to get it working but it's labeled experimental and it fails
half the tests. There are lot of missing features in Bionic (Android's libc)
that libc++ needs that we provide in Apportable and doing so we are able to
pass all the tests.

Apportable is more than just C++ though. It's about building a better NDK or
rather a platform that makes things consistent across the board with other
native environments like iOS. Native in Android is an afterthought which we
aim to change. We fix things like libc, C++, and provide you with a lot of low
level libraries you expect would be included.

Apportable also is the only place you are going to find a native profiler
today (baring awful hacks) or will get the latest version of clang that run on
Android either.

The idea is to save you time with inconstancies and make it easier to deal
with building native code for both (you can even use the same Xcode project
and target both from there).

We also support Objective-C and everything that you get from iOS so you can
even bring that code over.

~~~
checker659
Thanks for the detailed response. I'll definitely give you guys a try.

------
wetherbeei
I made a painless way to integrate native libraries into Java (Android NDK
support too) with some automatic JNI generation [1]. It uses GWT's javascript
comment syntax (edit: see [2] for examples).

[1]
[https://bitbucket.org/wetherbeei/acceljava](https://bitbucket.org/wetherbeei/acceljava)

[2]
[https://bitbucket.org/wetherbeei/acceljava/src/4140d721c11b5...](https://bitbucket.org/wetherbeei/acceljava/src/4140d721c11b564c46c415e8cbc9cbda1ef380f8/testproject/src/edu/illinois/crhc/acceljavatest/Test.java?at=master)

------
drawkbox
Most game engines are built as C/C++ and wrapped with Objective-C, Java, etc
wrappers. It is really easy with games because you just need an OpenGL context
and some basic views, everything else can happen in the render. When you have
to add native UI and integrate with libs like StoreKit, GameCenter, audio etc
those are also wrapped.

Still the best underlying tech is C/C++ for games. Even top engines like Unity
export to this format. It would be entirely limiting to build an entire engine
in Objective-C or Java for mobile multiplatform. C/C++ can be used everywhere
with a little bit of wrapping.

------
cshipley
I'm not quite sure I understand his objections to Xamarin. He says, "It can
only output to intermediate Xamarin libraries, not native ones."

On iOS Xamarin does compile down to native code and on Android is compiled to
dex format. They are not interpreted on those platforms.

Xamarin can utilize PCL assemblies, so non-ui code could be written once and
used multiple places without recompilation. This is actually very handy since
those libraries can be built on Windows, where the toolchain is better (IMO VS
is better than XS) and the system is more powerful.

~~~
jeopard
I'm sorry if this wasn't clear. The purpose of building this library was to
have something which could be distributable to any mobile developer, not just
the ones using Xamarin. If you did it through Xamarin, you could only give it
to Xamarin developers, which is very limiting. We need something that could be
importable by most developers, especially native SDK ones.

------
yeureka
We are developing a game engine in C++ that compiles and runs on iOS, Android,
Windows and OSX. We use the Marmalade SDK and though there are some issues
with it we are actually running the builds on all these environments without
issues which is pretty cool. And if Marmalade goes under we can still port the
lower layers to OpenGL.

------
jpsim
Just because support for multiple platforms is the goal doesn't mean that it
has to share the same code base.

Actually, for the author's simple use case (REST API), writing per-platform
would probably have taken as much code as the wrappers themselves. Not to
mention improved maintainability and a slew of other factors.

Diving down to C++ for cross-platform libraries starts to make sense when
there are 4-5+ platforms (certainly not 2), or if there are complex algorithms
(certainly not just a REST API), or if there's a very wide range of
functionality (i.e. 100+ API calls).

~~~
pjmlp
C++ is currently my language to go on mobile development, even if I nowadays
prefer GC enabled languages, because of:

\- experience with C++ since the ARM was published

\- only language common to all mobile OS SDKs and I not want to rely on third
party toolchains

\- C++11 makes it feel refreshing (except for compile times :\ )

\- I am only doing portable graphics related stuff as an hobby

\- RoboVM would be nice, but it is still kind of work in progress

In the OP case, you are right, but it could also be compensated with third
party libraries like Qt, instead of the DYI approach that was taken.

However with bigger teams with disparate skillsets, maybe something like Mono
would be a better approach.

~~~
frik
I hope you also support non ARM Android devices like Samsung Galaxy Tab 3
(Anrdoid 4x on Intel Atom x86) and there are also devices with MIPS CPU.

~~~
pjmlp
So far only hobby stuff, so I only target my own devices, but it is quite easy
to support multiple devices.

I am a bit older than C++, so I do know how to write portable code before we
had VMs everywhere. :)

------
general_failure
I think if you want to write xplatform c++, Qt is the way to go. Qt also has
QML that solves all the pains of flexible dynamic UI framework.

------
chacham15
I have a decent code base written in C/C++. Now as I am thinking about mobile
apps, I wonder if it is worth all the hassle on Andriod to go through all of
this or if it is just better to do a rewrite in Java. Does anyone have any
experience about this?

~~~
Iftheshoefits
That depends on what your "decent code base" is, what it is meant to
accomplish, how much coverage of your library is going to exist in your mobile
app, whether (and how often) you will actually re-use the core libraries, etc.

Realistically, what the OP is doing is pushing the maintenance and platform-
specific code into a different part of the stack. In either case, code in
different languages, with different native-interface specifications and
idioms, is required to be written and maintained. Unless you have some
certainty that the maintenance of the multiple different platform wrapper code
bases will be less laborious than simply writing platform-specific code, it's
probably not worth it.

In the worst case, for example, a new function in C or C++ that you write may
have to have one (or more!) new functions written in the platform-specific
wrapper code in order to utilize it.

------
kybernetyk
Why use explicit memory management in the iOS wrapper (delete in dealloc) when
ARC in conjunction with std::shared_ptr would take care of it automatically?

~~~
jeopard
In iOS, things are simple. The deallocating code is very concise and safe. Why
having the performance overhead of smart pointers? On the other hand, it could
be useful to have them in Java and avoid manual destruction. However, this
wasn't investigated :(

------
senthil_rajasek
link to Google cache...

[http://webcache.googleusercontent.com/search?q=cache:Y2AE0GA...](http://webcache.googleusercontent.com/search?q=cache:Y2AE0GAywcYJ:www.skyscanner.net/blogs/developing-
mobile-cross-platform-library-part-2-c+&cd=1&hl=en&ct=clnk&gl=us)

~~~
jeopard
it's back up

------
thrush
Great! Let's do the same thing for Browser Plugins now :)

------
jbeja
Interesting.

------
lingua_franca
this is not open sourced?

~~~
jeopard
No, unfortunately, it needs polishing before open-sourcing it. If there's
enough demand, I might consider it...

