Java调用C/C++有两种方式
第一种,这种是传统的命名规范,java_[以_代替.的全包名]_类名_方法名(JNIEnv* env, jobject[C++对应的java类实例],参数..)
这种写法,必须在对应的java类中有对应的方法名
jint java_com_ndk_testndk_TestHello_jnia(JNIEnv* env,jobject obj);
第二种写法,在Java代码中调用System.loadLibrary方法就会自动的调用JNI代码中的JNI_Onload方法
通过调用JNIEnv类实例的RegisterNatives方法,它一共有四个参数,第一,二,四个参数好理解,这里我们讲解下第三个参数是一个数组,
这个二维数组中的第一个数组包含了三个string,第一个"stringFromJNI"对应java中方法名,第二个"()Ljava/lang/String;"对应方法的返回类型和参数类型,在我的JNI学习随笔系列一中有具体讲解怎么使用,第三个是JNI中对应的方法,也可以认为是第一种写法中的C++方法。
# define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
jstring native_stringFromJNI( JNIEnv* env, jobject thiz )
{
return (*env)->NewStringUTF(env, "Hello from JNI !");
}
static const char *classPathName = "com/example/hellojni/HelloJni";
static JNINativeMethod methods[] = {
{"stringFromJNI", "()Ljava/lang/String;", (void*)native_stringFromJNI},
};
jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
JNIEnv* env = NULL;
jclass clazz;
//获取JNI环境对象
if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
LOGE("ERROR: GetEnv failed\n");
return JNI_ERR;
}
//注册本地方法.Load 目标类
clazz = (*env)->FindClass(env,classPathName);
if (clazz == NULL)
{
LOGE("Native registration unable to find class '%s'", classPathName);
return JNI_ERR;
}
//注册本地native方法
if((*env)->RegisterNatives(env, clazz, methods, NELEM(methods)) < 0)
{
LOGE("ERROR: MediaPlayer native registration failed\n");
return JNI_ERR;
}
/* success -- return valid version number */
return JNI_VERSION_1_4;
}
那么,如何在C/C++中调用java呢,具体代码如下:
JNIEnv* env;
jclass cls;//对用java的Class
jobject obj;
jmethodID mid;//映射方法
//构建一个Class
cls = jniEnv->FindClass("com/ndk/testndk/TestHello");//写上类的路径
//实例化对象
//方法一
obj = env->AllocObject(cls);
//方法二
jmethodID obj_id = env->GetMethodID(cls,"<init>", "()V");
TestProvider mTestProvider = env->NewObject(cls,obj_id);
//映射方法
//其中"()Ljava/lang/String;",括号是参数,Ljava/lang/String;是返回值,如有参数string,即为"(Ljava/lang/String;)Ljava/lang/String;"
//静态
mid = env->GetStaticMethodID(cls, "getStaticString","()Ljava/lang/String;");
//非静态
mid = env->GetMethodID(cls, "getString","()Ljava/lang/String;");
//调用方法
//静态:
env->CallStaticObjectMethod(cls, mid);
//非静态:
env->CallVoidMethod(obj, mid,jstr);
最后下一个系列,我们来具体讨论下C/C++中调用Java需要用到的一些API.