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

Running native code on Android #OSDCfr 2012

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: Running native code on Android #OSDCfr 2012

Running native code on Android

OSDC.fr 2012-10-13 Cédric @deltheil

C NDK ARM

Page 2: Running native code on Android #OSDCfr 2012

- Why using native code? -

Page 3: Running native code on Android #OSDCfr 2012

1. Reuse some C code

Page 4: Running native code on Android #OSDCfr 2012

2. Use 3rd party libraries

Page 5: Running native code on Android #OSDCfr 2012

3. Create portable components

iOSAndroid ...

Page 6: Running native code on Android #OSDCfr 2012

4. Use hardware acceleration

CPUSIMD algorithm

Page 7: Running native code on Android #OSDCfr 2012

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

Page 8: Running native code on Android #OSDCfr 2012

...but How?

Native Development Kit

Page 9: Running native code on Android #OSDCfr 2012

- Android NDK overview -

Page 10: Running native code on Android #OSDCfr 2012

Downloadshttp://developer.android.com/tools/sdk/ndk/index.html

cross-platform

Page 11: Running native code on Android #OSDCfr 2012

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

Page 12: Running native code on Android #OSDCfr 2012

Contents2. System files and headers for Android native APIs.

w/ Java Native Interface (a.k.a JNI) <jni.h>

Page 13: Running native code on Android #OSDCfr 2012

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

Page 14: Running native code on Android #OSDCfr 2012

Contents4. Documentation andcode samples.

Page 15: Running native code on Android #OSDCfr 2012

- Steps to embed C code -

Page 16: Running native code on Android #OSDCfr 2012

1/3 Wrap CJava

JNI

C code

C

Java

libmisc.so

Page 17: Running native code on Android #OSDCfr 2012

1/3 Wrap C

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

#include <jni.h>

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

namespace class method instancenative interface

Page 18: Running native code on Android #OSDCfr 2012

2/3 Build native libJava

JNI

C code

C

Java

libmisc.so

Page 19: Running native code on Android #OSDCfr 2012

# 2. Generate a lib with ndk-build

$ ndk-build Compile thumb : misc <= misc.cStaticLibrary : libmisc.aSharedLibrary : libmisc.soInstall : libmisc.so => libs/armeabi/libmisc.so...

2/3 Build native lib

Page 20: Running native code on Android #OSDCfr 2012

3/3 Java extJava

JNI

C code

C

Java

libmisc.so

Page 21: Running native code on Android #OSDCfr 2012

/* 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

Page 22: Running native code on Android #OSDCfr 2012

BasicJava

JNI

C code

C

Java

libmisc.so

Page 23: Running native code on Android #OSDCfr 2012

AdvancedJava

JNI

libA.a

C

Java

libmisc.so

A sources

C code

libB.a B sources

3rd party libs

Page 24: Running native code on Android #OSDCfr 2012

- Building 3rd party libs -

Page 25: Running native code on Android #OSDCfr 2012

Pro-tip

Use the Standalone Toolchain.

Page 26: Running native code on Android #OSDCfr 2012

What?

A customized install for a given platform, arch.

handy

Page 27: Running native code on Android #OSDCfr 2012

Why?

No need to write specific Android.mk makefiles: reuse existing build systems.

0 LOC Makefile autotools

Page 28: Running native code on Android #OSDCfr 2012

How?

Page 29: Running native code on Android #OSDCfr 2012

Makefile

[Ex. 1] jsmn

JSONC parser

Page 30: Running native code on Android #OSDCfr 2012

[Ex. 1] jsmn 1/3

override Makefile variables

Page 31: Running native code on Android #OSDCfr 2012

[Ex. 1] jsmn 2/3

Page 32: Running native code on Android #OSDCfr 2012

[Ex. 1] jsmn 3/3

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

Full gist @ http://git.io/ndk-jsmn

Page 33: Running native code on Android #OSDCfr 2012

[Ex. 2] msgpack

autotools binaryC/C+ serialization

Page 34: Running native code on Android #OSDCfr 2012

[Ex. 2] msgpack 1/3

Page 35: Running native code on Android #OSDCfr 2012

[Ex. 2] msgpack 2/3

Page 36: Running native code on Android #OSDCfr 2012

[Ex. 2] msgpack 3/3

Full gist @ http://git.io/ndk-msgpack

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

Page 37: Running native code on Android #OSDCfr 2012

- Using a prebuilt library -

Page 38: Running native code on Android #OSDCfr 2012

OverviewAndroid.mk

Application.mk

ndk-buildarmeabi/libfoo.so

libs/

single arch

Page 39: Running native code on Android #OSDCfr 2012

OverviewAndroid.mk

Application.mk

armeabi-v7a/libfoo.so

ndk-buildarmeabi/libfoo.so

libs/

fat binary

Page 40: Running native code on Android #OSDCfr 2012

- Loading a native library -

Page 41: Running native code on Android #OSDCfr 2012

Basic

Pick the right arch vs.

target device

Page 42: Running native code on Android #OSDCfr 2012

Medium

Page 43: Running native code on Android #OSDCfr 2012

Custom

frontal library

native method (frontal lib.)

Pick the right arch yourself!

Page 44: Running native code on Android #OSDCfr 2012

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

Page 45: Running native code on Android #OSDCfr 2012

- Quick JNI hints -

Page 46: Running native code on Android #OSDCfr 2012

C pointer = int fielde.g. persist a DB handle and use it throughout the JNI extensions

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

Page 47: Running native code on Android #OSDCfr 2012

C error codes

C error code & string