加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

[cocos2dx]在cocos2dx中通过Jni实现Java与C++的互相调用(一)

发布时间:2020-12-14 17:21:14 所属栏目:百科 来源:网络整理
导读:JNI相关知识 JNI的意思是java本地接口,通过jni可以实现java层代码和其他语言写得代码进行互调。 在cocos2d-x中,如果想要在c++层调用java层的代码,就是通过jni技术。通过调用java层的代码,我们就可以在Android平台下实现一些引擎没有提供给我们的功能,或

JNI相关知识

JNI的意思是java本地接口,通过jni可以实现java层代码和其他语言写得代码进行互调。在cocos2d-x中,如果想要在c++层调用java层的代码,就是通过jni技术。通过调用java层的代码,我们就可以在Android平台下实现一些引擎没有提供给我们的功能,或者做一些其他的功能。比如加个广告,加个分享,调用Android原生的对话框等等吧。Cocos2d-x比较人性化的是为我们封装了jni调用的一些接口,这个类就是JniHelper,我们只需要使用这个类提供给我们的接口就可以完成调用java层代码的功能,该文件位于cocos2d/cocos/platform/android/jni目录下。
要想使用JNI,必须得包含头文件,android是使用ndk编译c/c++的,这里jni.h文件位于:android-ndk-r8bplatformsandroid-14arch-armusrincludejni.h。

JniHelper类

通过JNI获取Java虚拟机,再获取当前程序的JNI环境,通过JNI环境获取需要调用的java类信息,再获取需要调用的java类中的函数信息。再通过JNI环境调用,使用类信息、函数信息,调用对应的java函数通过看JniHelper.cpp文件可以大致清楚这些。
头文件: #include "platform/android/jni/JniHelper.h"
需要使用的接口如下:
static bool getStaticMethodInfo(JniMethodInfo &methodinfo,const char *className,const char *methodName,const char *paramCode);
static bool getMethodInfo(JniMethodInfo &methodinfo,const char *paramCode);
实现上我们只需要使用上面这两个接口,就可以获取java类的所有函数信息了。JNI环境的获取、各种错误处理都已经在这两个接口实现中封装好了。先上代码,再来依次讲解每个参数的意义和使用方法:
    //函数信息结构体
    JniMethodInfo minfo;
    bool isHave = JniHelper::getStaticMethodInfo(minfo,/*JniMethodInfo的引用*/
                                                 "com/omega/MyApp",/*类的路径*/
                                                 "getJavaActivity",/*函数名*/
                                                 "()Ljava/lang/Object;");/*函数类型简写*/
    jobject activityObj;
    if (isHave)
    {
        //CallStaticObjectMethod调用java函数,并把返回值赋值给activityObj
        activityObj = minfo.env->CallStaticObjectMethod(minfo.classID,minfo.methodID);
    }
OK,很简单。上面的代码,就是使用JNI在C++中调用java类静态函数的典型使用方法。只有两步:
  1. 获取java函数的信息,classid、methodid等等
  2. 选择JNIEnv中的接口,进行函数调用

getStaticMethodInfo参数详解

getMethodInfo和getStaticMethodInfo这两个接口的参数一样,意义也相同,详解如下:
  • JniMethodInfo &methodinfo JniMethodInfo对象的引用,函数执行中会把jniEvn、classid、methodid写入到引用中。
  • const char *className 类的路径,把类的完整包名写全,用法如以上代码。
  • const char *methodName 函数名,函数名写上就行了。
  • const char *paramCode 函数类型简写,它的格式为:(参数)返回类型。如:无参数,void返回类型函数,其简写为 ()V
java中的类型对应的简写如下:
参数类型 参数简写
boolean Z
byte B
char C
short S
int I
long J
float F
double D
void V
Object Ljava/lang/Object;
String Ljava/lang/String;
Array [

多参数的函数

如果函数有多个参数,直接把简写并列即可。注意Object与String型参数简写结尾的分号,示例:
  • (IIII)V ==> void fun(int a,int b,int c,int d)
  • (ILjava/lang/String;I)Ljava/lang/String; ==> string fun(int x,String a,int y)
  • (ILjava/lang/String;[I)J ==> long fun(int n,String s,int[] arr)

通过JNIEnv进行函数调用

JNIEvn有一系列的CallStatic[返回类型]Method、Call[返回类型]Method接口,需要针对不同的函数返回类型选择调用。[返回类型]以函数返回类型的不同,对应不同的函数名。例如: CallStaticVoidMethod ——void; CallVoidMethod ——void
其对应关系如下:
函数名
函数返回值类型
Void void
Object jobject
Boolean jboolean
Byte jbyte
Char jchar
Short jshort
Int jint
Long jlong
Float jfloat
Double jdouble
参数传递
调用有参数的java函数时,需要把对应的参数传递进去。需要把参数按顺序加入到classid、methodid后面,并且需要做类型转换。例如:
jint jX = 10;
jint jY = 10;
minfo.env->CallStaticVoidMethod(minfo.classID,minfo.methodID,jX,jY);
参数类型转换关系如下:
C++类型 JAVA类型 jboolean byte jbyte jchar short jshort jint long jlong jfloat double jdouble Object jobject Class jclass jstring Object[] jobjectArray boolean[] jbooleanArray byte[] jbyteArray char[] jcharArray short[] jshortArray int[] jintArray long[] jlongArray float[] jfloatArray double[] jdoubleArray
string类型的转换
实际上我们最常用的参数类型,主要是内建的数据类型、string字符串类型。数据类型可以直接转为j类型,但是string类型需要做如下处理:
jstring jmsg = minfo.env->NewStringUTF("http://www.baidu.com");
minfo.env->CallStaticVoidMethod(minfo.classID,jmsg);

非静态函数的调用

非静态函数的调用与静态函数的调用类似,但是需要通过一个静态函数获取java类对象。
    JniMethodInfo info;
    bool ret = JniHelper::getStaticMethodInfo(info,"org/cocos2dx/cpp/TestJniHelper","getObj","()Ljava/lang/Object;");
    //先获得类的对象,然后用这个对象去调用它的非静态函数
    jobject jobj;
    if(ret)
    {
        log("call static method");
        jobj = info.env->CallStaticObjectMethod(info.classID,info.methodID);
    }
    //getMethodInfo判断java定义的类非静态函数是否存在,返回bool
    bool re = JniHelper::getMethodInfo(info,"func","()V");
    if(re)
    {
        log("call no-static method");
        //非静态函数调用的时候,需要的是对象,所以与静态函数调用的第一个参数不同
        info.env->CallVoidMethod(jobj,info.methodID);
    }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
    站长推荐
    热点阅读