JNI学习随笔系列二

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.

转载于:https://www.cnblogs.com/ncuboy-045wsq/p/4202312.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值