转载

【基础1】JniHelper静态函数和非静态函数的调用

都知道基础很重要,那我就把基础写一下,这样显得自己记住了一样。

JniHelper ,顾名思义。就是帮助使用JNI的一个办法。他的存在就是为 让我们在游戏开发中调用Java变得更加简单。

要使用JniHelper,首先得知道它的头文件在哪 platform/android/jni/下的JniHelper.h。那先打开这个这个头文件,看看给我们提供了什么。我把cocos3.3版的这个头文件的对外接口折叠贴在这了。

【JniHelper.h】

typedef struct JniMethodInfo_ {  JNIEnv * env;  jclass   classID;  jmethodID   methodID; } JniMethodInfo; public:  static void setJavaVM(JavaVM *javaVM);  static JavaVM* getJavaVM();  static JNIEnv* getEnv();  static bool setClassLoaderFrom(jobject activityInstance);  static bool getStaticMethodInfo(JniMethodInfo &methodinfo,          const char *className,          const char *methodName,          const char *paramCode);  static bool getMethodInfo(JniMethodInfo &methodinfo,          const char *className,          const char *methodName,          const char *paramCode);  static std::string jstring2string(jstring str);  static jmethodID loadclassMethod_methodID;  static jobject classloader; 

首先是要给结构体,里面三个成员 第一个JNIEnv* 先知道通过他可以操作javaVm, 然后他的本质其实首先指向一个线程相关的结构,该结构又指向一个指针数组,在这个指针数组中的每个元素最终指向一个JNI函数。所以可以通过JNIEnv去调用JNI函数。这里记住就好了。而通过jclass 和jmethod 这两个结构体成员 就可以实现需要操作哪个Java类中的哪个成员方法了。

这一快说的就是如何通过这个神器调用java的静态成员函数和普通成员函数。

【静态函数的调用】

静态函数,可以说是属于这个类的,在OC上就是类方法的概念(ps,今天刚刚开始着手ios平台,看了一点)。也就是说这个方法是属于这个类的,而这个类的所有实例共享这个方法。所以访问这个方法应该是简单一点的。思路呢,首先是得到得到结构体,因为里面存着那么重要的信息。通过getStaticMethodInfo就可以得到这个参数,有了这些参数就好说了,下面看代码

void JniUCPlatform::dologout() {  JniMethodInfo info;//定义结构体  jobject obj;         /**   * 得到info信息  *    * @param info 这个是个传出参数,也就是我们需要得到的info   * @param "String" 类路径  * @param "String" 静态函数名  * @param "String" 函数参数和返回值   */  if(JniHelper::getStaticMethodInfo(info,"android/ucplatform/UCPlatform","getObj","()Ljava/lang/Object;"))  {   obj = info.env->CallStaticObjectMethod(info.classID, info.methodID);  }  info.env->DeleteLocalRef(info.classID);//这个Delete一下吧。你会感谢自己的这个动作的

}

就跟上面代码一样,这样就完成了调用java层的静态函数。这个例子的函数参数是空,如果有参数的话,只按照JNI的规则来进行转换就好了。其中String操作的比较常见,类似下面的这样的配套使用,JNI文档上是有一大堆的。

jstring jRoleId = info.env->NewStringUTF(roleId);

info.env->DeleteLocalRef(jRoleId);

const char * _productid = info->GetStringUTFChars(productid, NULL);

info->ReleaseStringUTFChars(productid, _productid);

【非静态函数的调用】

非静态函数,在OC中叫实例方法,就是属于某一个实例的,只能通过一个实例访问它,那么问题也就来了,我们先要得到这个类的Object,才可以拿到这个非静态函数的使用权力。所以流程是这样的:可以写一个JAVA静态方法,这个方法是得到Objec的。然后用JniHelper调用这个函数拿到Object,再通过这个Object调用非静态函数。下面看代码

void JniUCPlatform::dologin() {  JniMethodInfo info;  jobject obj;  if(JniHelper::getStaticMethodInfo(info,"android/ucplatform/UCPlatform","getObj","()Ljava/lang/Object;"))  {   obj = info.env->CallStaticObjectMethod(info.classID, info.methodID);  }   //这里就是调用普通函数,只要注意Call方法中的第一参数不再是classID,而是上一步得到的obj;  if(JniHelper::getMethodInfo(info,"android/ucplatform/UCPlatform","login", "()V"))  {   info.env->CallVoidMethod(obj, info.methodID);  }  info.env->DeleteLocalRef(info.classID); }
正文到此结束
Loading...