Slide 1

Slide 1 text

Running native code on Android OSDC.fr 2012-10-13 Cédric @deltheil C NDK ARM

Slide 2

Slide 2 text

- Why using native code? -

Slide 3

Slide 3 text

1. Reuse some C code

Slide 4

Slide 4 text

2. Use 3rd party libraries

Slide 5

Slide 5 text

3. Create portable components iOS Android ...

Slide 6

Slide 6 text

4. Use hardware acceleration CPU SIMD algorithm

Slide 7

Slide 7 text

5. ... because it’s fun :)

Slide 8

Slide 8 text

...but How? Native Development Kit

Slide 9

Slide 9 text

- Android NDK overview -

Slide 10

Slide 10 text

Downloads http://developer.android.com/tools/sdk/ndk/index.html cross-platform

Slide 11

Slide 11 text

Contents 1. Tools for Linux,OS X,Win to cross-compile native ARM,x86,MIPS binaries.

Slide 12

Slide 12 text

Contents 2. System files and headers for Android native APIs. w/ Java Native Interface (a.k.a JNI)

Slide 13

Slide 13 text

Contents 3. Easy-to-use build system: Android.mk & ndk-build (make wrapper).

Slide 14

Slide 14 text

Contents 4. Documentation and code samples.

Slide 15

Slide 15 text

- Steps to embed C code -

Slide 16

Slide 16 text

1/3 Wrap C Java JNI C code C Java libmisc.so

Slide 17

Slide 17 text

1/3 Wrap C /* 1. Wrap your C code with the JNI */ #include jstring Java_com_example_Foo_bar(JNIEnv* env, jobject thiz) { char buffer[512]; /* ... */ return (*env)->NewStringUTF(env, buffer); } namespace class method instance native interface

Slide 18

Slide 18 text

2/3 Build native lib Java JNI C code C Java libmisc.so

Slide 19

Slide 19 text

# 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 ... 2/3 Build native lib

Slide 20

Slide 20 text

3/3 Java ext Java JNI C code C Java libmisc.so

Slide 21

Slide 21 text

/* 3. Expose the logic via a native extension */ package com.example; public class Foo extends /* ... */ { static { System.loadLibrary("misc"); } public native String bar(); } 3/3 Java ext

Slide 22

Slide 22 text

Basic Java JNI C code C Java libmisc.so

Slide 23

Slide 23 text

Advanced Java JNI libA.a C Java libmisc.so A sources C code libB.a B sources 3rd party libs

Slide 24

Slide 24 text

- Building 3rd party libs -

Slide 25

Slide 25 text

Pro-tip Use the Standalone Toolchain.

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

Why? No need to write specific Android.mk makefiles: reuse existing build systems. 0 LOC Makefile autotools

Slide 28

Slide 28 text

How?

Slide 29

Slide 29 text

Makefile [Ex. 1] jsmn JSON C parser

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

[Ex. 1] jsmn 2/3

Slide 32

Slide 32 text

[Ex. 1] jsmn 3/3 choose the proper arch... and that’s it! Full gist @ http://git.io/ndk-jsmn

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

[Ex. 2] msgpack 1/3

Slide 35

Slide 35 text

[Ex. 2] msgpack 2/3

Slide 36

Slide 36 text

[Ex. 2] msgpack 3/3 Full gist @ http://git.io/ndk-msgpack use the cross-toolchains... and that’s it!

Slide 37

Slide 37 text

- Using a prebuilt library -

Slide 38

Slide 38 text

Overview Android.mk Application.mk ndk-build armeabi/ libfoo.so libs/ single arch

Slide 39

Slide 39 text

Overview Android.mk Application.mk armeabi-v7a/ libfoo.so ndk-build armeabi/ libfoo.so libs/ fat binary

Slide 40

Slide 40 text

- Loading a native library -

Slide 41

Slide 41 text

Basic Pick the right arch vs. target device

Slide 42

Slide 42 text

Medium

Slide 43

Slide 43 text

Custom frontal library native method (frontal lib.) Pick the right arch yourself!

Slide 44

Slide 44 text

Custom: why? [2] Bypass a loadLibrary bug on ICS! [1] Properly target ARMv7 without NEON CPUs when getCpuFeatures() can’t be used at runtime (e.g. 3rd party libs) [2] see http://www.moodstocks.com/2012/03/20/ice-cream-sandwich-why-native-code-support- sucks [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

Slide 45

Slide 45 text

- Quick JNI hints -

Slide 46

Slide 46 text

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)

Slide 47

Slide 47 text

C error codes C error code & string

Slide 48

Slide 48 text

Resources #AltDevBlogADay NDK Part 1 & Part 2 Linux Mag., 07/11 VLC for Android Tokyo Cabinet Java Pkg

Slide 49

Slide 49 text

Thanks! Questions? Comments? [email protected] | @deltheil