cocos2dx JNI 中 C++层与Java层之间的交互

来源:互联网 发布:诺亚网络萝卜街 编辑:程序博客网 时间:2024/05/22 01:49

Cocos2d-x 中C++与java之间的交互通信

这里我们先大的区分有两种:

(1)    在Java层调用C++层

首先我们要注意并使用的一个关键字就是native


注:这里说明下 这个static的使用是有个规则:是static 函数中不可访问非static的成员

   当你的java层,这里使用exitApp的时候注意下就好。

 

在C++层我们要接收到这个exitApp():

包含两个JNI头文件


#if(CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID)

extern "C" {

          //免费礼包150钻石

JNIEXPORT void JNICALLJava_com_joniy_gamecandy_MainActivity_exitApp(JNIEnv *env, jobject obj)

{

        UserInfo::shareUserInfo()->menoy+= 150;

}

}

 

///这里分析下内容:

CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID):判断机型,业务需求

:这里是固定写法

:这里是调用函数在java项目里的位置

 

:函数名,这里要和你的java层的名字一模一样(有参无参也必须一样),这里出错了,好像编译不会出错,如果不小心的话,很难检查出问题。

JNIEnv *env, jobjectobj:这俩参数是JNI的基本固定写法,我没怎么使用到,但是解释我给一段链接这个解释的非常不错

http://blog.csdn.net/jiangwei0910410003/article/details/17465457

 

如果需要传参数的话,C++这里在后面添加就好例如:

JNIEXPORT void JNICALLJava_org_cocos2dx_cpp_MyHelper_setMoney(JNIEnv *env, jobject thiz,jint money)

 

注意类型的定义  ,这里的类型需要使用JNI里面的,其实很简单基本类型加一个J,大概有哪些我举几个(这是网上找的方便大家看)

Java类型     本地类型   字节(bit)
  boolean   jboolean   8, unsigned
  byte    jbyte     8
  char    jchar    16, unsigned
  short    jshort    16
  int     jint     32
  long    jlong    64
  float    jfloat    32
  double   jdouble   64
  void    void     n/a

(2)从C++层调用Java层的函数方法

1.直接调用

#if(CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID)

JniMethodInfo t;

         if(JniHelper::getStaticMethodInfo(t,"com/fengk/movestar/gahepay/CommonBillingUtils","openfreegift", "()V")) {

                   t.env->CallStaticVoidMethod(t.classID,t.methodID);

                   t.env->DeleteLocalRef(t.classID);

         }

#else

         CCLog("!!!!!!!!!!!!!!!!!!open_free_gift!!!!!!!!!!!!!!!!!!!!!!");

#endif

注意几点即可:

JniMethodInfo t: 声明一个JNI调用方法的实例(这里偷懒下,我理解是这样,一般固定写)

:openfreegift() 该方法在java的位置用‘/’隔开,后面节参数

getStaticMethodInfo: 获取该方法

CallStaticVoidMethod:调用该方法

 

Java 层写法

Public static openfreegift(){}

//注意这里两边一定要统一,你是用静态方法调用


对应的Java层一定是静态的(这里我忘了,这出错好不好调了,一定注意)

 

2.如果带参数传递的话例子如下

void CallJni::openGiftLayer(int giftType)

{

#if(CC_PLATFORM_ANDROID ==CC_TARGET_PLATFORM)

         JniMethodInfominfo;

         jobjectjobj;

         if(JniHelper::getStaticMethodInfo(minfo,"com/sf/plane/airraid", "getInstance","()Ljava/lang/Object;"))

         {

                   jobj= minfo.env->CallStaticObjectMethod(minfo.classID, minfo.methodID);

                   if(JniHelper::getMethodInfo(minfo,"com/sf/plane/airraid", "c_call_java_openGift","(I)V"))

                   {

                            minfo.env->CallVoidMethod(jobj,minfo.methodID,giftType);

                   }

         }

#endif

         CCLOG("-----------------------giftType = ---- %d ", giftType);

}

///这段代码说两点

一个是参数:

传入方法是这样的代表的是返回值为void的有一个参数方法

传入两个参数可以这样写"(IJ)V"。

 

另一个就是写法习惯:


我们在构建Java代码是,声明一个类之后,我们一般会先会得到这个类的对象,然后在调用这个类里面的方法。(这样写的好处好像是确保对象的唯一性,有时候因为网络各种原因,我们可能得不到这个对象,进而直接使用它的方法时会出错)

//注:之前好像处理过一个bug,就是Java中自己使用了一个对象,C++这里调用了getInstance也生成了一个对象,所以,你们在构建getInstance这个方法是注意加些判断。

 

//还有点大家可能注意到了我们一般用到调用方法的时候:有两对

静态获取:getStaticMethodInfo  使用:CallStaticVoidMethod(无返回参数的) CallStaticObjectMethod(返回参数是对象)

非静态获取getMethodInfo  使用:CallVoidMethod

若果Java有返回值的情况话我举个例子

Java 层假设我们需要调用它boolean function(int a,double b,char c){}

 

C++层应该使用env->CallBooleanMethod(jobj,minfo.methodID1,3.14,“aaa)

 

//第一次写文档希望对大家有帮助,如果那里解释有误,请多包涵,多指正。

阅读全文
0 0
原创粉丝点击