Running native
    code on Android
           C       NDK   ARM




Cédric @deltheil               OSDC.fr 2012-10-13
- Why using native
     code? -
1. Reuse some C
      code
2. Use 3rd party
    libraries
3. Create portable
   components
   Android   iOS   ...
4. Use hardware
  acceleration
  SIMD   CPU   algorithm
5. ... because it’s
        fun :)
...but How?




Native Development Kit
- Android NDK
  overview -
Downloads
http://developer.android.com/tools/sdk/ndk/index.html




                                           cross-platform
Contents
1. Tools for Linux,OS X,Win to cross-compile
native ARM,x86,MIPS binaries.
Contents
2. System files and headers for Android native
APIs.




           w/ Java Native Interface (a.k.a JNI) <jni.h>
Contents
3. Easy-to-use build system: Android.mk &
ndk-build (make wrapper).
Contents
4. Documentation and
code samples.
- Steps to embed C
       code -
1/3 Wrap C
            Java


          libmisc.so




Java
             JNI
 C


           C code
1/3 Wrap C

/* 1. Wrap your C code with the JNI */

#include <jni.h>

jstring
Java_com_example_Foo_bar(JNIEnv* env, jobject thiz) {
  char buffer[512];
  /* ... */
  return (*env)->NewStringUTF(env, buffer);
}


namespace   class   method   native interface   instance
2/3 Build native lib
          Java


        libmisc.so




Java
           JNI
 C


         C code
2/3 Build native lib

# 2. Generate a lib with ndk-build

$ ndk-build
Compile thumb   :   misc <= misc.c
StaticLibrary   :   libmisc.a
SharedLibrary   :   libmisc.so
Install         :   libmisc.so => libs/armeabi/libmisc.so
...
3/3 Java ext
             Java


           libmisc.so




Java
              JNI
 C


            C code
3/3 Java ext
/* 3. Expose the logic via a native extension */

package com.example;

public class Foo extends /* ... */ {

    static {
      System.loadLibrary("misc");
    }

    public native String bar();

}
Basic
         Java


       libmisc.so




Java
          JNI
 C


        C code
Advanced
                            Java


                      libmisc.so




     Java
                            JNI
       C


3rd party libs             C code

A sources         libA.a            libB.a   B sources
- Building 3rd
  party libs -
Pro-tip


Use the Standalone Toolchain.
What?

A customized install for a given platform,
arch.
 handy
Why?

No need to write specific Android.mk
makefiles: reuse existing build systems.
  0 LOC    Makefile    autotools
How?
[Ex. 1] jsmn




Makefile   C   JSON   parser
[Ex. 1] jsmn 1/3




override Makefile variables
[Ex. 1] jsmn 2/3
[Ex. 1] jsmn 3/3




choose the proper arch... and that’s it!


            Full gist @ http://git.io/ndk-jsmn
[Ex. 2] msgpack




autotools   C/C+   binary   serialization
[Ex. 2] msgpack 1/3
[Ex. 2] msgpack 2/3
[Ex. 2] msgpack 3/3




use the cross-toolchains... and that’s it!


           Full gist @ http://git.io/ndk-msgpack
- Using a prebuilt
     library -
Overview
Android.mk




                                     libs/
                       ndk-build
                                   armeabi/
                                   libfoo.so



Application.mk


                            single      arch
Overview
Android.mk




                                     libs/
                       ndk-build
                                    armeabi/
                                    libfoo.so

                                   armeabi-v7a/
                                   libfoo.so
Application.mk


                             fat        binary
- Loading a native
     library -
Basic




Pick the right
   arch vs.
target device
Medium
Custom
    frontal library

    native method (frontal lib.)



          Pick the right arch
               yourself!
Custom: why?

[1] Properly target ARMv7 without NEON CPUs
when getCpuFeatures() can’t be used at
runtime (e.g. 3rd party libs)


[2] Bypass a loadLibrary bug on ICS!

[1] e.g. «the NVidia Tegra 2 generation SoC has a dual-core ARM Cortex-A9 CPU (lacking ARM's
advanced SIMD extension—NEON)» - see http://en.wikipedia.org/wiki/Tegra
[2] see http://www.moodstocks.com/2012/03/20/ice-cream-sandwich-why-native-code-support-
sucks
- Quick JNI hints -
C pointer = int field
                                          e.g. persist a DB handle
                                          and use it throughout
                                          the JNI extensions




Don’t forget to destruct it (explicitly
or at finalize() time)
C error codes




            C error code
            & string
Resources
#AltDevBlogADay NDK Part 1 & Part 2   Linux Mag., 07/11




       Tokyo Cabinet Java Pkg          VLC for Android
Thanks!


Questions? Comments? cedric@moodstocks.com | @deltheil

Running native code on Android #OSDCfr 2012