1:java 是如何和C /C++完成调用的
通过 在java 层 定义 native 方法,然后在 用C 或者C++ 实现,打包成.so 文件 在java层调用
示例:
// 测试JAVA的NDK调用
public native String stringFromJNI();
// 测试C/C++中对JAVA函数的静态回调
public native static int jniStaticShowMessage(Context ctx, String strTitle, String strMessage);
// 测试实例中C/C++中对JAVA类的函数的调用
public native int jniShowMessage(Context ctx, String strTitle, String strMessage);
// 测试创建新实例C/C++对JAVA类的函数的调用
public native int jniInstanceShowMessage(Context ctx, String strTitle, String strMessage);
static {
System.loadLibrary("demo-jni");
}
这是方法定义:
这个是用C 来实现的
#include <string.h>
#include <jni.h>
// 加载此动态库时系统自动首先加载
jint JNI_OnLoad(JavaVM* vm, void *reserved)
{
JNIEnv *env;
if((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_4) != JNI_OK)
{
return -1;
}
return JNI_VERSION_1_4;
}
jstring
Java_study_jnidemo_JniDemoActivity_stringFromJNI( JNIEnv* env,jobject thiz )
{
return (*env)->NewStringUTF(env, "JniDemo, Hello from zhangggai ");
}
jstring
combine_jstring(JNIEnv* env, jstring str1, jstring str2)
{
jboolean b_ret;
const char *s1 = (*env)->GetStringUTFChars(env, str1, &b_ret);
const char *s2 = (*env)->GetStringUTFChars(env, str2, &b_ret);
int n1 = strlen(s1);
int n2 = strlen(s2);
char *new_str = (char *)malloc(n1+n2+1);
memset(new_str, 0, n1+n2+1);
strcat(new_str, s1);
strcat(new_str, s2);
jstring ret_str = (*env)->NewStringUTF(env,(const char *)new_str);
free(new_str);
return ret_str;
}
jint
Java_study_jnidemo_JniDemoActivity_jniStaticShowMessage(JNIEnv* env, jobject thiz,
jobject ctx, jstring strTitle, jstring strMessage)
{
jclass cls = (*env)->FindClass(env, "study/jnidemo/JniDemoActivity");
if(cls != NULL)
{
jmethodID id = (*env)->GetStaticMethodID(env, cls,
"staticShowMessage",
"(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)I");
if(id != NULL)
{
return (*env)->CallStaticIntMethod(env, cls, id, ctx, strTitle, strMessage);
}
}
return 1;
}
// 在当前已有的JAVA实例中调用
jint
Java_study_jnidemo_JniDemoActivity_jniShowMessage(JNIEnv* env, jobject thiz,
jobject ctx, jstring strTitle, jstring strMessage)
{
jclass cls = (*env)->GetObjectClass(env, thiz);
if(cls != NULL)
{
jstring str;
jmethodID strTest_id = (*env)->GetMethodID(env, cls, "getTestString",
"()Ljava/lang/String;");
if(strTest_id != NULL)
{
str = (*env)->CallObjectMethod(env, thiz, strTest_id);
}
jmethodID showMessage_id = (*env)->GetMethodID(env, cls, "showMessage",
"(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)I");
if(showMessage_id != NULL)
{
return (*env)->CallIntMethod(env, thiz, showMessage_id, ctx,
strTitle, combine_jstring(env, strMessage, str));
}
}
return 1;
}
// 在新建JAVA实例中调用
jint
Java_study_jnidemo_JniDemoActivity_jniInstanceShowMessage(JNIEnv* env, jobject thiz,
jobject ctx, jstring strTitle, jstring strMessage)
{
jclass cls = (*env)->FindClass(env, "study/jnidemo/JniDemoActivity");
if(cls != NULL)
{
// get instance
jmethodID constuctor_id = (*env)->GetMethodID(env, cls, "<init>", "()V");
if(constuctor_id != NULL)
{
jobject obj = (*env)->NewObject(env, cls, constuctor_id);
if(obj != NULL)
{
jstring str;
jmethodID strTest_id = (*env)->GetMethodID(env, cls, "getTestString",
"()Ljava/lang/String;");
if(strTest_id != NULL)
{
str = (*env)->CallObjectMethod(env, obj, strTest_id);
}
jmethodID showMessage_id = (*env)->GetMethodID(env, cls, "showMessage",
"(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)I");
if(showMessage_id != NULL)
{
return (*env)->CallIntMethod(env, obj, showMessage_id, ctx,
strTitle, combine_jstring(env, strMessage, str));
}
}
}
}
return 1;
}