writing native code for android systems n.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
Writing Native Code for Android Systems PowerPoint Presentation
Download Presentation
Writing Native Code for Android Systems

Loading in 2 Seconds...

play fullscreen
1 / 18

Writing Native Code for Android Systems - PowerPoint PPT Presentation


  • 148 Views
  • Uploaded on

Writing Native Code for Android Systems. Why ndk. There exist large c++ code libraries E.g., Audio and video compression, e.g., Ogg Vorbis , The LAME Project (mp3), .. OpenGL O penSL ES Low level audio Advanced CPU features

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'Writing Native Code for Android Systems' - stefan


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
why ndk
Why ndk
  • There exist large c++ code libraries
    • E.g., Audio and video compression, e.g., OggVorbis, The LAME Project (mp3), ..
  • OpenGL
  • OpenSL ES
    • Low level audio
  • Advanced CPU features
    • E.g., some ARM cpu support the NEON instruction set for signal and video processing
slide3

App are mixed java and c/c++

  • The java app is like a regular app. The java app is started by os.
    • It is not possible to have a stand alone c++ program (not sure, it might be)
  • The c++ program is placed in a shared library
    • Shared libraries have names like libMyProgram.so
  • The application package (.apk) will include the java app and the shared library
  • jni (Java Native Interface) must be used to move data between java and c++
outline of steps
Outline of Steps
  • Write c++ code in MyProject/jni
  • Describe project sources in MyProject/jni/Android.mk
    • Like a make file, but much easier
  • Build project by running the command ../android-ndk-r5b/ndk-build from your MyProject directory
    • ndk-build is like make
      • ndk-build
        • Builds
      • Ndk-build clean
        • Cleans everything
    • Generates shared lib (libXX.so file) and places it in correct directory so the java program can get it
  • Make .apk file by building app in eclipse
    • Important: whenever you make a change in the c++ program, of coruse, you need to run ndk-build. But, you also must rerun the java compile. To do this, make a trivial change in your java code and resave.
hellojni
HelloJni
  • Make new app called
    • Package: edu.udel.eleg454.HelloJni
    • Activity Name: HelloJni
    • Project: HelloJni
  • Make new subdirectory in project call jni
    • i.e., HelloJni/jni
  • In jni directory make new file called
    • MyHelloJni.cpp
  • In this file, put
    • #include <string.h>
    • #include <jni.h>
    • extern "C" {
    • JNIEXPORT jstring JNICALL
    • Java_edu_udel_eleg454_helloJni_HelloJni_stringFromJNI( JNIEnv* env,
    • jobjectthiz )
    • {
    • return env->NewStringUTF("Hello from JNI!");
    • }
    • }
  • Save file
  • Important: function names must be exactly correct
    • Java_packageNameWithDotReplacedByUnderScore_JavaClassNameThatWillCallThisFunction_functionName
android mk
Android.mk
  • In HelloJni/jni make new file called Android.mk
  • Put the following in Android.mk
    • LOCAL_PATH := $(call my-dir)
    • include $(CLEAR_VARS)
    • LOCAL_MODULE := HelloJni
    • LOCAL_SRC_FILES := HelloJni.cpp
    • include $(BUILD_SHARED_LIBRARY)
  • Note that LOCAL_MODULE is the module name
  • Build library
    • Open terminal.
    • Cd dir to <workspace>/HelloJni/jni
    • Run build
      • <android-ndk-r5b>/ndk-build
    • Check that libHelloJni.so is created
in java hellojni
In java HelloJni
  • After public class HelloJni extends Activity {
    • public native String stringFromJNI(); // the c++ function name
    • static {
    • System.loadLibrary("HelloJni"); // shared lib is called libHelloJni.so.
      • // this name is from the LOCAL_MODULE part of the Android.mk file
    • }
    • Note: HelloJni is our
  • In onCreate, after setContentView(R.layout.main); put
    • Log.e("debug","callingjni");
    • Log.e("debug",stringFromJNI()); // last part of name of c++ function
    • Log.e("Debug","done");
  • Run and check log
  • Note: public native … allows any function to be defined. But when this function is called, the shared library must have already been loaded (via System.loadLibrary)
slide8
play
  • Change c++ function to be make string
    • Hello from JNI 2
  • Instead of
    • Hello from JNI!
  • Rebuild and run from eclipse
    • Log does not show anything. Not even an error
  • In eclipse make trivial change (delete and add ;)
  • Run, and everything is ok
c function name
C++ Function name
  • Change c++ function name. recompile and see error in LogCat
    • “no implementation found for native …”
  • Make a new class called TestJni
  • Move jni stuff into TestJni
  • Run and see error
  • Change function name from
    • Java_edu_udel_eleg454_helloJni_HelloJni_stringFromJNI
  • To
    • Java_edu_udel_eleg454_helloJni_TestJni_stringFromJNI
  • And runs ok
logging from c
Logging from c++
  • In cpp file, add
    • #include <android/log.h>
  • In Android.mk add
    • LOCAL_LDLIBS := -llog
  • In function add
    • __android_log_print(ANDROID_LOG_INFO, “DEBUG", “Here we are");
passing strings from java to c with jni
Passing strings from java to c++ with JNI
  • In java code, make function arg include a string
    • Change
      • public native String stringFromJNI();
    • To
      • public native String stringFromJNI(String name);
    • And change
      • Log.e("debug",stringFromJNI());
    • To
      • Log.e("debug",stringFromJNI("string para"));
  • In c++ code
    • Change
      • JNIEXPORT jstring JNICALL
      • Java_edu_udel_eleg454_helloJni_HelloJni_stringFromJNI( JNIEnv* env,
      • jobjectthiz)
    • To
      • JNIEXPORT jstring JNICALL
      • Java_edu_udel_eleg454_helloJni_HelloJni_stringFromJNI( JNIEnv* env,
      • jobjectthiz, jstringjavaString )
    • And add
      • const char *str = env->GetStringUTFChars(javaString, 0); // convert java string to c++str
      • __android_log_print(ANDROID_LOG_INFO, "DEBUG", str); // do something
      • env->ReleaseStringUTFChars(javaString, str); // release str
  • Build, compile, run
  • Note: after release, str is no longer valid
passing int floats etc to c
Passing int, floats, etc to c++
  • In java
    • Change
      • public native String stringFromJNI();
    • To
      • public native String stringFromJNI(intval);
    • And change
      • Log.e("debug",stringFromJNI());
    • To
      • inti = 100;
      • Log.e("debug",stringFromJNI(i));
  • In c++
    • Change
      • JNIEXPORT jstring JNICALL
      • Java_edu_udel_eleg454_helloJni_HelloJni_stringFromJNI( JNIEnv* env,
      • jobjectthiz)
    • To
      • JNIEXPORT jstring JNICALL
      • Java_edu_udel_eleg454_helloJni_HelloJni_stringFromJNI( JNIEnv* env,
      • jobjectthiz, jintji )
    • And comment out
      • const char *str = env->GetStringUTFChars(javaString, 0);
      • env->ReleaseStringUTFChars(javaString, str);
    • Add
      • char str[80];
      • sprintf(str,"data is %d",ji); // be sure to add #include <stdio.h>
      • __android_log_print(ANDROID_LOG_INFO, "DEBUG", str);
  • Build, compile, run
jni data types
Jni Data types
  • C++ type = jave type
  • unsigned char = jboolean
  • signed char = jbyte
  • unsigned short = jchar
  • Short = jshort
  • Long = jlong
  • Long long = jlong
  • __int64 = jlong
  • float = jfloat
  • double = jdouble
passing arrays of ints to c
Passing arrays of ints to c++
  • In java
    • Define function to take int array as argument
      • Replace
        • public native String stringFromJNI();
      • With
        • public native String stringFromJNI(int[] val);
    • In onCreate
      • Make array
        • int[] ints = new int[]{1,1,2,3,5,8,13};
      • Call function with ints as augment
        • Log.e("debug",stringFromJNI(ints));
passing arrays of ints to c1
Passing arrays of ints to c++
  • In c++
    • Define function to take array as argument
      • JNIEXPORT jstring JNICALL
      • Java_edu_udel_eleg454_helloJni_HelloJni_stringFromJNI( JNIEnv* env,
      • jobjectthiz, jintArrayjiArray )
    • Get size of array
      • jsizearrayLength = env->GetArrayLength(jiArray);
      • char str[80];
      • __android_log_print(ANDROID_LOG_INFO, "DEBUG", str);
    • Get pointer to array
      • jint *data = env->GetIntArrayElements(jiArray, 0);
    • Do something with data
      • for (inti=0; i<arrayLength; i++) {
        • sprintf(str,"val %d is %d",i,data[i]);
        • __android_log_print(ANDROID_LOG_INFO, "DEBUG", str);
        • data[i] = i;
      • }
    • Release pointer
      • env->ReleaseIntArrayElements(jiArray, data, 0);
  • Build, compile, run
more passing arrays to c
More passing arrays to c++
  • env->ReleaseIntArrayElements(jiArray, data, 0);
    • Last argument is 0 => data is copied back to java and java can delete data array
    • Last argument is JNI_COMMIT => data is copied back, but java should not delete the array
    • Last argument is JNI_ABORT => data is not copied back and java can delete
  • Check if the data was changed in c++
    • In java, after Log.e("debug",stringFromJNI(ints)); add
      • for (int i=0; i<ints.length; i++) {
      • Log.e("DEBUG","ret val["+i+"] = "+ints[i]);
      • }
    • run, and see that ints is updated
returning data
Returning data
  • Java
    • define function to return int
      • public native intstringFromJNI(int[] val);
    • Call function and print return value
      • Log.e("debug","results = "+stringFromJNI(ints));
  • C++
    • Change function prototype to return jint
      • JNIEXPORT jint JNICALL
      • Java_edu_udel_eleg454_helloJni_HelloJni_stringFromJNI( JNIEnv* env,
      • jobjectthiz, jintArrayjiArray )
    • return int
      • return 12;
  • Build, compile, run
return arrays
Return arrays
  • Same as returning a string but use NewIntArray