Android:NDK:Sample
lastmod 2023-05-09created 2016-06-223 edits
Compiling with cygwin bash on Windows
To compile, the following environment variables must be set first.
- CYGWIN_HOME: the directory where cygwin is installed.
- NDK_HOME: the directory where the NDK is installed. (It must be added to the PATH variable.)
Basic structure of Android.mk
The basic form of Android.mk, read by the Makefile, is as follows.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# 여기 이후에 추가 설정 정보를 입력해야 한다.
# LOCAL_DEFAULT_CPP_EXTENSION := cpp
LOCAL_MODULE := [LIBRARY_NAME]
LOCAL_SRC_FILES := [SRC_FILES]
# 여기 이전에 추가 설정 정보 입력을 완료해야 한다.
include $(BUILD_SHARED_LIBRARY)
-
$(LOCAL_MODULE): name of the output library file.
(The file name gets the prefix lib and the suffix .so.) -
$(LOCAL_SRC_FILES): list of source files to compile.
Android.mk Macro List
The predefined macros in Android.mk, read by the Makefile, are as follows.
-
$(NDK_PROJECT_PATH): ndk project path. -
$(NDK_APP_APPLICATION_MK): specifies the*.mkfile that ndk-build will read.
Adding C/C++ usage to Android.mk
Add the CPP file extension as shown below. Note that it must be inserted after include $(CLEAR_VARS). (When compiling directly in Cygwin, c is compiled with gcc and cpp with g++.)
Linking a JNI Library to a Java class
In the class you want to link the JNI library to, load the library using System.loadLibrary() as shown below. (Note that the library name must be the same as $(LOCAL_MODULE) in Android.mk, with the prefix lib and the suffix .so removed.)
package com.example;
public class TestNdkActivity extends Activity {
static {
System.loadLibrary("libraryname");
}
}
Linking a Method
When using a C function of JNI from Java, add the native keyword as shown below.
Note that the function name must be written exactly on the Native code side, i.e., the C side, under the following conditions.
- When using C++, make it C using
extern "C". - When using C++, add
JNIEXPORTbefore the return type. - When using C++, add
JNICALLbetween the return type and the function name. - Write the function name in the following order.
- Write
Java_as the prefix. - Write the package name in order, converting each period (.) to an underscore (). (Do not use an underscore () or a hyphen (-) in the package name.)
- Write the class name to use. (Prefix it with an underscore (_) to separate it from the package name.)
- Write the Method name to use. (Prefix it with an underscore (_) to separate it from the package name.)
- Write
- The first parameter is fixed as
JNIEnv* env. - The second parameter is fixed as
jobject thiz. - From the third parameter on, use the order of the parameters passed from Java.
Example
To help understanding, here is an example of a function that meets the following conditions.
Language(C++), Package(com.example), class(TestNdkActivity) Method(private native String getJniTestString):
#include <jni.h>
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jstring JNICALL
Java_com_example_TestNdkActivity_getJniTestString(JNIEnv* env, jobject thiz) {
return env->NewStringUTF("Hello, NDK!");
}
#ifdef __cplusplus
}
#endif
Differences between C and C++ implementations
When using the NDK, C and C++ are used differently.
C implementation:
#include <string.h>
#include <jni.h>
jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env, jobject thiz ) {
return (*env)->NewStringUTF(env, "Hello from JNI !");
}
C++ implementation:
#include <string.h>
#include <jni.h>
JNIEXPORT jstring JNICALL Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env, jobject thiz ) {
return env->NewStringUTF("Hello, NDK!");
}
About the Android NDK Samples
- http://developer.android.com/tools/sdk/ndk/overview.html
- http://blog.naver.com/PostView.nhn?blogId=bluekms21&logNo=10141500106
Description of the sample projects included when installing the NDK:
- hello-jni: example that loads a string from a shared library implementing a native method and displays it in the application UI.
- two-libs: example that dynamically loads a shared library and calls the native method it provides. The native method is implemented in a static library and imported into the shared library.
- san-angeles: example that renders 3D graphics using the native OpenGL ES API. During rendering, the activity lifecycle is managed by a GLSurfaceView Object.
- hello-gl2: example that renders a triangle using OpenGL ES 2.0 vertex & fragment shaders.
- hello-neon: example that checks CPU capabilities at runtime with the cpufeature library (when the CPU supports NEON intrinsics). This example is implemented in two versions: a C version (tiny benchmark for a FIR filter loop) and a NEON-optimized version.
- bitmap-plasma: example showing how to access the pixel buffer of an Android Bitmap Object from native code.
- native-activity: example showing how to create a native activity with the native-app-glue static library.
- native-plasma: the bitmap-plasma example implemented as a native activity.