cocos2dx---c++与java互调

     使用cocos2dx开发游戏过程中难免需要调用其他代码,因为其是跨平台的。必然会要去调用不同平台的代码,这篇博客就介绍如何使用Jni来实现c++与java代码的互调。

     先实现c++调用Android的java层代码。我们先添加一个类,比如类名叫CallJava,下面贴上代码,再做解释:

 1 #ifndef __CALL_JAVA_H__
 2 #define __CALL_JAVA_H__
 3 
 4 #include "cocos2d.h"
 5 USING_NS_CC;
 6 
 7 #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
 8 class CallJava
 9 {
10 public:
11     void static initCall();
12     void static loginCall();
13     void static closeCall();
14 };
15 
16 
17 #endif
18 
19 #endif // __CALL_JAVA_H__
CallJava.h
 1 #include "CallJava.h"
 2 
 3 #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
 4 #include "platform/android/jni/JniHelper.h"
 5 #include <jni.h>
 6 #include <android/log.h>
 7 void CallJava::initCall()
 8 {
 9     JniMethodInfo minfo;
10 
11     bool isHave = JniHelper::getStaticMethodInfo(minfo,"org/cocos2dx/call/CallJava","initCall","(Ljava/lang/String;I)V");
12     if (isHave)
13     {
14 
15         jstring jstr = minfo.env->NewStringUTF("init_call");
16 
17         minfo.env->CallStaticVoidMethod(minfo.classID, minfo.methodID,jstr,2000);
18         minfo.env->DeleteLocalRef(minfo.classID);
19     }
20     else
21     {
22         CCLOG("func is not exited...");
23     }
24     
25 }
26 
27 
28 void CallJava::loginCall()
29 {
30     JniMethodInfo minfo;
31 
32     bool isHave = JniHelper::getStaticMethodInfo(minfo,"org/cocos2dx/call/CallJava","loginCall","(Ljava/lang/String;)V");
33     if (isHave)
34     {
35 
36         jstring jstr = minfo.env->NewStringUTF("login_call");
37 
38         minfo.env->CallStaticVoidMethod(minfo.classID, minfo.methodID,jstr);
39         minfo.env->DeleteLocalRef(minfo.classID);
40     }
41     else
42     {
43         CCLOG("func is not exited...");
44     }
45 
46 }
47 
48 void CallJava::closeCall()
49 {
50     JniMethodInfo minfo;
51 
52     bool isHave = JniHelper::getStaticMethodInfo(minfo,"org/cocos2dx/call/CallJava","CloseCall","()V");
53     if (isHave)
54     {
55         minfo.env->CallStaticVoidMethod(minfo.classID, minfo.methodID);
56         minfo.env->DeleteLocalRef(minfo.classID);
57     }
58     else
59     {
60         CCLOG("func is not exited...");
61     }
62 
63 }
64 #endif
CallJava.cpp

头文件没啥好说的,我们重点说说cpp文件。。。

JniHelper::getStaticMethodInfo(minfo,"org/cocos2dx/call/CallJava","initCall","(Ljava/lang/String;I)V");

 

"org/cocos2dx/call/CallJava"就是要调用函数的路径,“initCall”当然就是函数名了,

"(Ljava/lang/String;I)V" 就是(参数)返回值的意思。 这里函数的参数是string和int类型,返回值void

参数、返回值对照表如下:

jstring jstr = minfo.env->NewStringUTF("init_call"); 这是java的string类型的本地表示,int->jint,诸如此类...

minfo.env->CallStaticVoidMethod(minfo.classID, minfo.methodID,jstr,2000); 函数的意思是调用静态方法,后面2个参数就是传进去的字符串和int值。第一个参数在调用CallVoidMethod方法是不用传的。。。

好,下面看看java层代码的实现:因为我们的路径是"org/cocos2dx/call/CallJava",所以我们在project.android下的src文件夹添加一个包org/cocos2dx/call,然后添加一个CallJava文件

 

 1 package org.cocos2dx.call;
 2 
 3 import android.app.Activity;
 4 import android.os.Bundle;
 5 import android.os.Message;
 6 import android.util.Log;
 7 import android.widget.Toast;
 8 import org.cocos2dx.cpp.AppActivity;
 9 import org.cocos2dx.lib.Cocos2dxActivity;
10 
11 
12 public class CallJava {
13  
14     public static void initCall(String str,int i)
15     {
16             
17         Message msg = new Message();
18         
19         Bundle bundle = new Bundle();
20         bundle.putString("key", str);
21         bundle.putInt("id", i);
22         msg.what = AppActivity.call_login;
23         msg.setData(bundle);
24         
25         AppActivity.getInstance()._handler.sendMessage(msg);
26                 
27     }
28     
29     
30     public static void loginCall(String str)
31     {
32         
33         Message msg = new Message();
34         
35         Bundle bundle = new Bundle();
36         bundle.putString("key", str);
37         
38         msg.what = AppActivity.call_login;
39         msg.setData(bundle);
40         
41         AppActivity.getInstance()._handler.sendMessage(msg);
42                 
43     }
44     
45     public static void CloseCall()
46     {
47         CallCpp.exit();
48     }
49 }
CallJava.java

这里的3个方法,对应这上面cpp文件的三个方法,就是JniHelper::getStaticMethodInfo方法的第三个参数。关于这里面的实现不多说,是android的消息机制,这里写在了另个AppActivity.java文件中,一会贴上代码。

我们先看第三个函数CloseCall()的实现

 

1     public static void CloseCall()
2     {
3         CallCpp.exit();
4     }

 

 

CallCpp是src文件夹下的另个文件CallCpp.java的类名,exit是它的一个函数,代码如下

1 package org.cocos2dx.call;
2 
3 public class CallCpp {
4     public static native void init(String str,int i);
5     public static native void login(String str);
6     public static native void exit();
7 }

JNI是Java Native Interface的 缩写。如果你想将一个方法做为一个本地方法的话,那么你就必须声明改方法为native的,并且不能实现。

看看c++层这几个函数的对应调用

 

 1 #ifndef __CALL_CPP_H__
 2 #define __CALL_CPP_H__
 3 
 4 #include "cocos2d.h"
 5 USING_NS_CC;
 6 
 7 #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
 8 #include <jni.h>
 9 extern "C"
10 {
11     void Java_org_cocos2dx_call_CallCpp_init(JNIEnv *,jobject,jstring,jint);
12     void Java_org_cocos2dx_call_CallCpp_login(JNIEnv *,jobject,jstring);
13     void Java_org_cocos2dx_call_CallCpp_exit(JNIEnv *,jobject);
14 };
15 
16 
17 
18 #endif
19 
20 #endif // __CALL_CPP_H__
CallCpp.h

 

解释下函数名的意思,首先Java_ 后面是 包名,类名,函数名。

 1 #include "CallCpp.h"
 2 #include "HelloWorldScene.h"
 3 
 4 #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
 5 #include "platform/android/jni/JniHelper.h"
 6 #include <jni.h>
 7 
 8 void Java_org_cocos2dx_call_CallCpp_init(JNIEnv *env,jobject thiz,jstring str,jint id)
 9 {
10     std::string msg = JniHelper::jstring2string(str);
11     int i = id;
12     MessageBox(msg.c_str(),"C++");
13 
14 }
15 
16 void Java_org_cocos2dx_call_CallCpp_login(JNIEnv *env,jobject thiz,jstring str)
17 {
18     std::string msg = JniHelper::jstring2string(str);
19     MessageBox(msg.c_str(),"C++");
20 
21 }
22 
23 void Java_org_cocos2dx_call_CallCpp_exit(JNIEnv *env,jobject thiz)
24 {
25 
26     HelloWorld* main = HelloWorld::getInstance();
27     if (main)
28     {
29          Director::getInstance()->end();
30     }
31 }
32 #endif
CallCpp.cpp

我们看下实现效果:

 

转载于:https://www.cnblogs.com/OrangeLife/p/4375149.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值