NDK Integration (JNI)

advertisement
NDK Integration (JNI)
Lecture 5
Operating Systems Practical
11 November 2015
This work is licensed under the Creative Commons Attribution 4.0 International License. To view a copy of this
license, visit http://creativecommons.org/licenses/by/4.0/.
OSP
NDK Integration (JNI), Lecture 5
1/31
JNI
Android JNI Example
Native Method Arguments
Mapping of Types
Operations on Strings
OSP
NDK Integration (JNI), Lecture 5
2/31
Outline
JNI
Android JNI Example
Native Method Arguments
Mapping of Types
Operations on Strings
OSP
NDK Integration (JNI), Lecture 5
3/31
JNI
I
Java Native Interface (JNI)
I
Native Programming Interface
I
Allows Java code to interoperate with apps and libraries
written in other programming languages
When do we use JNI?
I
I
I
I
OSP
Java library does not support platform-dependent features
Use already existent library written in other language
Time-critical code in a low level language (performance)
NDK Integration (JNI), Lecture 5
4/31
JNI
OSP
I
Two-way interface
I
Allows Java apps to invoke native code and vice versa
NDK Integration (JNI), Lecture 5
5/31
Two-way Interface
I
I
Support for two types of native code
Native libraries
I
I
I
Native applications
I
I
I
OSP
Call functions from native libraries
In the same way they call Java methods
Embed a Java VM implementation into native apps
Execute components written in Java
e.g. C web browser executes applets in an embedded Java VM
implementation
NDK Integration (JNI), Lecture 5
6/31
Implications of Using JNI
I
Java apps are portable
I
I
I
I
Java is type-safe and secure
I
I
I
I
I
C/C++ are not
Misbehaving native code can affect the whole application
Security checks when invoking native code
Extra care when writing apps that use JNI
Native methods in few classes
I
OSP
Run on multiple platforms
The native component will not run on multiple platforms
Recompile the native code for the new platform
Clean isolation between native code and Java app
NDK Integration (JNI), Lecture 5
7/31
Android NDK
I
Android Native Development Kit
I
I
I
ndk-build
I
I
I
I
OSP
Allows the embed C/C++ (native) code in Android
applications
Implement your own native code or use existing native libraries
Shell script that invokes the NDK build scripts
Probe the development system and app project file to decide
what to build
Generate binaries
Copy binaries in the app’s project path
NDK Integration (JNI), Lecture 5
8/31
Outline
JNI
Android JNI Example
Native Method Arguments
Mapping of Types
Operations on Strings
OSP
NDK Integration (JNI), Lecture 5
9/31
Basic JNI Example - Android.mk
I
Android.mk
I
I
I
I
I
Configuration file
In /jni
The name of the native source file: hello-jni.c
The name of the shared library to build: hello-jni
Built library: libhello-jni.so
LOCAL PATH := $ ( c a l l my−d i r )
i n c l u d e $ ( CLEAR VARS )
LOCAL MODULE
:= h e l l o − j n i
LOCAL SRC FILES := h e l l o − j n i . c
i n c l u d e $ ( BUILD SHARED LIBRARY )
OSP
NDK Integration (JNI), Lecture 5
10/31
Basic JNI Example - Application.mk
I
Application.mk
I
I
I
In /jni
Specifies the CPU and architecture for building
In this example - all supported architectures
APP ABI := a l l
OSP
NDK Integration (JNI), Lecture 5
11/31
Basic JNI Example - Java code
I
Java source code in /src
I
I
I
Load native library in a static initializer
Declare the native function (native keyword)
Call the native function
package com . e x a m p l e . h e l l o j n i ;
p u b l i c c l a s s H e l l o J n i extends A c t i v i t y
{
@Override
p u b l i c void onCreate ( Bundle s a v e d I n s t a n c e S t a t e )
{
super . onCreate ( savedInstanceState ) ;
TextView
t v = new TextView ( t h i s ) ;
tv . setText ( stringFromJNI () ) ;
setContentView ( tv ) ;
}
public native String
stringFromJNI ( ) ;
static {
System . l o a d L i b r a r y ( ” h e l l o − j n i ” ) ;
}
}
OSP
NDK Integration (JNI), Lecture 5
12/31
Basic JNI Example - Native code
I
C source code in /jni
I
I
I
I
Implements the native function
Includes jni.h
Function name - based on the Java function name and the
path to the file containing it
Arguments:
I
I
I
JNIEnv * - pointer to the VM, called interface pointer
jobject - implicit this object passed from the Java side
Creates a string by using a JNI function (NewStringUTF)
#i n c l u d e < s t r i n g . h>
#i n c l u d e < j n i . h>
jstring
J a v a c o m e x a m p l e h e l l o j n i H e l l o J n i s t r i n g F r o m J N I ( JNIEnv ∗ env ,
jobject thiz )
{
r e t u r n ( ∗ e n v)−>NewStringUTF ( env , ” H e l l o from JNI ” ) ;
}
OSP
NDK Integration (JNI), Lecture 5
13/31
Outline
JNI
Android JNI Example
Native Method Arguments
Mapping of Types
Operations on Strings
OSP
NDK Integration (JNI), Lecture 5
14/31
JNIEnv interface pointer
I
I
I
I
I
OSP
Passed into each native method call as the first argument
Valid only in the current thread (cannot be used by other
threads)
Points to a location that contains a pointer to a function table
Each entry in the table points to a JNI function
Native methods access data structures in the Java VM
through JNI functions
NDK Integration (JNI), Lecture 5
15/31
JNIEnv interface pointer
I
I
For C and C++ source files the syntax for calling JNI
functions differs
C code
I
I
I
JNIEnv is a pointer to a JNINativeInterface structure
Pointer needs to be dereferenced first
JNI functions do not know the current JNI environment
I
I
I
e.g. return (*env)->NewStringUTF(env, "Hello!");
C++ code
I
I
I
I
OSP
JNIEnv instance should be passed as the first argument to the
function call
JNIEnv is a C++ class
JNI functions exposed as member functions
JNI functions have access to the current JNI environment
e.g. return env->NewStringUTF("Hello!");
NDK Integration (JNI), Lecture 5
16/31
Second Argument
I
Second argument depends whether the method is static or
instance
I
Instance methods - can be called only on a class instance
I
Static methods - can be called directly from a static context
I
Both can be declared as native
For instance native method
I
I
I
I
For static native method
I
I
OSP
Reference to the object on which the method is invoked (this
in C++)
e.g. jobject thisObject
Reference to the class in which the method is defined
e.g. jclass thisClass
NDK Integration (JNI), Lecture 5
17/31
Outline
JNI
Android JNI Example
Native Method Arguments
Mapping of Types
Operations on Strings
OSP
NDK Integration (JNI), Lecture 5
18/31
Mapping of Types
I
I
JNI defines a set of C/C++ types corresponding to Java types
Java types
I
I
OSP
Primitive types: int, float, char
Reference types: classes, instances, arrays
I
The two types are treated differently by JNI
I
int -> jint (32 bit integer)
I
float -> jfloat (32 bit floating point number)
NDK Integration (JNI), Lecture 5
19/31
Primitive Types
Java Type
boolean
byte
char
short
int
long
float
double
OSP
JNI Type
jboolean
jbyte
jchar
jshort
jint
jlong
jfloat
jdouble
C/C++ Type
unsigned char
char
unsigned short
short
int
long long
float
double
NDK Integration (JNI), Lecture 5
Size
unsigned 8 bits
signed 8 bits
unsigned 16 bits
signed 16 bits
signed 32 bits
signed 64 bits
32 bits
64 bits
20/31
Objects
I
Objects -> opaque references
I
C pointer to internal data structures in the Java VM
Objects accessed using JNI functions (JNIEnv interface
pointer)
I
I
I
All JNI references have type jobject
I
I
I
OSP
e.g. GetStringUTFChars() function for accessing the
contents of a string
All reference types are subtypes of jobject
Correspond to the most used types in Java
jstring, jobjectArray, etc.
NDK Integration (JNI), Lecture 5
21/31
Reference Types
Java Type
java.lang.Class
java.lang. String
java.lang.Throwable
other objects
java.lang.Object[]
boolean[]
byte[]
char[]
short[]
int[]
long[]
float[]
double[]
other arrays
OSP
Native Type
jclass
jstring
jthrowable
jobject
jobjectArray
jbooleanArray
jbyteArray
jcharArray
jshortArray
jintArray
jlongArray
jfloatArray
jdoubleArray
jarray
NDK Integration (JNI), Lecture 5
22/31
Outline
JNI
Android JNI Example
Native Method Arguments
Mapping of Types
Operations on Strings
OSP
NDK Integration (JNI), Lecture 5
23/31
String Types
I
I
String is a reference type in JNI (jstring)
Cannot be used directly as native C strings
I
I
I
JNI supports UTF-8 and UTF-16/Unicode encoded strings
I
I
I
I
I
OSP
Need to convert the Java string references into C strings and
back
No function to modify the contents of a Java string
(immutable objects)
UTF-8 compatible with 7-bit ASCII
UTF-8 strings terminated with ’\0’ char
UTF-16/Unicode
Two sets of functions
jstring is represented in Unicode in the VM
NDK Integration (JNI), Lecture 5
24/31
Convert C String to Java String
I
NewStringUTF, NewString
jstring javaString = env->NewStringUTF("Hello!");
I
I
Takes a C string, returns a Java string reference type
If the VM cannot allocate memory
I
I
I
OSP
Returns NULL
OutOfMemoryError exception thrown in the VM
Native code should not continue
NDK Integration (JNI), Lecture 5
25/31
Convert Java String to C String
I
GetStringUTFChars, GetStringChars
const jbyte* str = env->GetStringUTFChars(javaString, &isCopy);
const jchar* str = env->GetStringChars(javaString, &isCopy);
I
isCopy
I
I
I
OSP
JNI_TRUE - returned string is a copy of the chars in the
original instance
JNI_FALSE - returned string is a direct pointer to the original
instance (pinned object in heap)
Pass NULL if it’s not important
I
If the string contains only 7-bit ASCII chars you can use
printf
I
If the memory allocation fails it returns NULL, throws
OutOfMemory exception
NDK Integration (JNI), Lecture 5
26/31
Release Strings
I
Free memory occupied by the C string
I
ReleaseStringUTFChars, ReleaseStringChars
env->ReleaseStringUTFChars(javaString, str);
OSP
I
String should be released after it is used
I
Avoid memory leaks
I
Frees the copy or unpins the instance (copy or not)
NDK Integration (JNI), Lecture 5
27/31
Length and Copy in Buffer
I
Get string length
I
I
I
GetStringUTFLength/GetStringLength on the jstring
Or strlen on the GetStringUTFChars result
Copy string elements into a preallocated buffer
env->GetStringUTFRegion(javaString, 0, len, buffer);
I
I
I
I
OSP
start index and length
length can be obtained with GetStringLength
buffer is char[]
No memory allocation, no out-of-memory checks
NDK Integration (JNI), Lecture 5
28/31
Critical Region
I
GetStringCritical, ReleaseStringCritical
I
Increase the probability to obtain a direct pointer to the string
Critical Section between the calls
I
I
I
I
I
I
OSP
Must not make blocking operations
Must not allocate new objects in the Java VM
Disable garbage collection when holding a direct pointer to a
string
Blocking operations or allocating objects may lead to deadlock
No GetStringUTFCritical -> usually makes a copy of the
string
NDK Integration (JNI), Lecture 5
29/31
Bibliography
OSP
I
http://www.soi.city.ac.uk/~kloukin/IN2P3/
material/jni.pdf
I
http://docs.oracle.com/javase/6/docs/technotes/
guides/jni/spec/jniTOC.html
I
http://download.java.net/jdk8/docs/technotes/
guides/jni/spec/functions.html
I
http://developer.android.com/training/articles/
perf-jni.html
I
Onur Cinar, Pro Android C++ with the NDK, Chapter 3
I
Sylvain Ratabouil, Android NDK, Beginner’s Guide, Chapter 3
NDK Integration (JNI), Lecture 5
30/31
Keywords
Java Native Interface
I
Primitive types
I
Two-way interface
I
Reference types
I
Native methods
I
JNI functions
I
Interface pointer
I
Opaque reference
I
Static methods
I
Java string reference
I
Instance methods
I
Conversion operations
I
OSP
NDK Integration (JNI), Lecture 5
31/31
Download