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.methodID,1,3.14,“aaa”)
//第一次写文档希望对大家有帮助,如果那里解释有误,请多包涵,多指正。