Android JNI - hqzhang/cloudtestbed GitHub Wiki
- declare native function that defined in CPP layer
public class Hellojnicpp extends Activity {
private native void native_wiper_init();
private static native void native_wiper_class_init();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.d(tag, "onCreate()*****1");
Toast.makeText(getApplicationContext(),"&&&&&&&&&"+
MainHelloService.string,
Toast.LENGTH_LONG).show();
//Intent myint= new Intent(this, );
}
/** A native method that is implemented by the
* ‘hello-jni’ native library, which is packaged
* with this application.
*/
public native String stringFromJNI();
/** Load the native library where the native method
* is stored.
*/
static {
System.loadLibrary("hello-jni");
native_wiper_class_init();
}
/*callback function*/
public void callback(String msg)
{
Toast.makeText(getApplicationContext(),"HQ Java callback:"+msg,
Toast.LENGTH_LONG).show();
}
/*callforward function*/
public void CallJNI(View view)
{
String hello = stringFromJNI();
Toast.makeText(getApplicationContext(),"get from C:"+ hello,
Toast.LENGTH_LONG).show();
//Intent intent = new Intent(this,android.basic.lesson14.MusicService.class);
//bindService(intent,conn,Context.BIND_AUTO_CREATE);
}
}
- register native table and call next layer interface
#include <string.h>
#include <stdio.h>
#include <jni.h>
#include <android/log.h>
#include "ulp.h"
#include <dlfcn.h>
#include <stdlib.h>
static jobject jWiper = NULL;
static jmethodID midCallBackStr;
int main_init(void);
int call_function();
//create object wiper
static void instanceInit(JNIEnv *env, jobject obj) {
if (NULL == jWiper) {
jWiper = env->NewGlobalRef(obj);
}
}
static void classInit(JNIEnv* env, jclass clazz) {
midCallBackStr = (env)->GetMethodID( clazz,
"callback", "(Ljava/lang/String;)V");
main_init();
}
static jstring stringFromJNI (JNIEnv *env, jobject Obj) //called by jv
{
//jclass thisClass = (env)->GetObjectClass( Obj);
//jmethodID midCallBackStr = (env)->GetMethodID( thisClass,
// "callback", "(Ljava/lang/String;)V");
//if (NULL == midCallBackStr) return;
__android_log_print(ANDROID_LOG_DEBUG,"hello-jni.cpp","%s","c++ callback**");
printf("In C++, call back Java's called(String)\n");
fflush(stdout);
call_function(); //call second layer cpp
}
static jstring callback(JNIEnv *env, jobject Obj){ //callback
jstring message = (env)->NewStringUTF( "Hello from C++");
(env)->CallVoidMethod( Obj, midCallBackStr, message);
return env->NewStringUTF("Hello from C++ over JNI!******");
}
//name mapping table
static JNINativeMethod method_table[] = {//6
{"native_wiper_class_init", "()V", (void *)classInit},
{"native_wiper_init", "()V", (void *)instanceInit},
{"stringFromJNI", "()Ljava/lang/String;", (void*)stringFromJNI}
};
//using name mapping table
extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* env;
if ( vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6 )!= JNI_OK ){//8
return -1;
}
else {
jclass clazz = env->FindClass("com/example/Hellojnicpp");
if(clazz){
env->RegisterNatives(clazz, method_table, sizeof(method_table)/sizeof(method_table[0]));
env->DeleteLocalRef(clazz);
return JNI_VERSION_1_6;
}else return -1;
}
return JNI_VERSION_1_6;
}
/** Another method using interface */
static void location_callback();
UlpCallbacks sUlpCallbacks = {
sizeof(UlpCallbacks),
location_callback
};
typedef void (*simple_forward)(void);
//typedef const ulpInterface* (get_ulp_interface) (void);
static void location_callback(){
__android_log_print(ANDROID_LOG_DEBUG,"hello-jni.cpp","%s","enter locationcallback in main###############\n");
}
const ulpInterface* loc_eng_ulpInf = NULL;
//init function for loading next module.
int main_init(void) {
const char *error;
void *module;
__android_log_print(ANDROID_LOG_DEBUG,"hello-jni.cpp","%s", "enter main_lib\n");
/* Load dynamically loaded library */
module = dlopen("libhello.so", RTLD_LAZY);
if (!module) {
__android_log_print(ANDROID_LOG_DEBUG,"hello-jni.cpp","%s",
"Couldn't open libhello.so:\n");
exit(1);
}
/* call init interface *///
__android_log_print(ANDROID_LOG_DEBUG,"hello-jni.cpp","%s", "enter main_lib:dslsym\n");
get_ulp_interface* get_ulp_inf;
const ulpInterface* loc_eng_ulpInf = NULL;
dlerror(); /* Clear any existing error */
__android_log_print(ANDROID_LOG_DEBUG,"hello-jni.cpp","%s", "enter main_lib:dslsym1\n");
get_ulp_inf = (get_ulp_interface*) dlsym(module , "ulp_get_interface");
if ((error = dlerror()) != NULL) {
__android_log_print(ANDROID_LOG_DEBUG,"hello-jni.cppfir","%s", error);
__android_log_print(ANDROID_LOG_DEBUG,"hello-jni.cppsec","%s", dlerror());
return 0;
}
__android_log_print(ANDROID_LOG_DEBUG,"hello-jni.cpp","%s", "enter main_lib:dslsym3\n");
__android_log_print(ANDROID_LOG_DEBUG,"hello-jni.cpp","%s", "enter main_lib:->init\n");
// Initialize the ULP interface
loc_eng_ulpInf = get_ulp_inf(); //for interface design
loc_eng_ulpInf->init(&sUlpCallbacks);
}
// forward function
int call_function(){
if(!loc_eng_ulpInf)__android_log_print(ANDROID_LOG_DEBUG,"hello-jni.cpp","%s", "ERROR main_lib:forward\n");
/* use pointer to call*/
else loc_eng_ulpInf->forw();
__android_log_print(ANDROID_LOG_DEBUG,"hello-jni.cpp","%s", "enter main_lib:finish\n");
/* All done, close things cleanly */
//dlclose(module);
return 0;
}
3 define interface struct and getInterface function in first layer
#include <string.h>
#include <stdio.h>
#include <jni.h>
#include <android/log.h>
#include <stdio.h>
#include "ulp.h"
extern "C" {
int ulp_init(UlpCallbacks *cb);
void forward ();
static ulpInterface ulpInf =
{
sizeof(ulpInterface),
ulp_init,
forward
};
UlpCallbacks *globalcb;
ulpInterface* ulp_get_interface () //call this by upper cpp
{
__android_log_print(ANDROID_LOG_DEBUG,"hello- jni1.cpp","%s","enter ulp_get_interface ().\n");
return &ulpInf;
}
int ulp_init(UlpCallbacks *cb){ //init by upper cpp
__android_log_print(ANDROID_LOG_DEBUG,"hello-jni1.cpp","%s","enter ulp_init function to set callback\n");
globalcb = cb;
return 0;
}
void forward () { //forward to callback to upper cpp
__android_log_print(ANDROID_LOG_DEBUG,"hello-jni1.cpp","%s","enter forward () and call callback from main **************\n");
globalcb->location_cb();
}
}
4 just header file
#include <stdio.h>
//#ifdef __cplusplus
//extern "C" {
//#endif
typedef void (* ulp_callback)(void);
/** ULP callback structure. */
typedef struct {
size_t size;
ulp_callback location_cb;
} UlpCallbacks;
typedef struct {
unsigned int size;
int (*init)(UlpCallbacks *cb);
void (*forw)(void);
}ulpInterface;
typedef const ulpInterface* (get_ulp_interface) (void);
#ifdef __cplusplus
//}
#endif}