Cocos2dx C++ Java相互调用

最近在接入android渠道sdk时遇到一些问题,整理一下以备后查(开发引擎是cocos2d-x):
1.c++调用java函数:通过jni来访问;
 例A:

 void TKSDKFunc::login()
 {
  #if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
 JniMethodInfo t;
 if (JniHelper::getStaticMethodInfo(t
 , "org/cocos2dx/cpp/AppActivity"
 , "start_login"
 , "()V"))
 {
 t.env->CallStaticVoidMethod(t.classID, t.methodID);
 t.env->DeleteLocalRef(t.classID);
 }
 # endif
 }

 start_login是一个无返回值无形参的静态函数;


 例B:

void TKSDKFunc::saveRoleInfo(string roleId,string rolelevel,string roleName,string area)
 {
  #if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
 JniMethodInfo t;
 if (JniHelper::getStaticMethodInfo(t, "org/cocos2dx/cpp/AppActivity", "save_roleInfo", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V")) {
 jstring str0;
 jstring str1;
 jstring str2;
 jstring str3;
 str0=t.env->NewStringUTF(roleId.c_str());
 str1=t.env->NewStringUTF(rolelevel.c_str());
 str2=t.env->NewStringUTF(roleName.c_str());
 str3=t.env->NewStringUTF(area.c_str());
 t.env->CallStaticVoidMethod(t.classID, t.methodID, str0,str1,str2,str3);
 t.env->DeleteLocalRef(str0);
 t.env->DeleteLocalRef(str1);
 t.env->DeleteLocalRef(str2);
 t.env->DeleteLocalRef(str3);
 t.env->DeleteLocalRef(t.classID);
 }
  #endif
}

save_roleInfo是一个无返回值有形参的静态函数,形参为jstring类型,注意列表中 Ljava/lang/String; 后面带的是分号

 例C:

 bool TKSDKFunc::isInWifi()
 {
 #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
JniMethodInfo t;
if (JniHelper::getStaticMethodInfo(t, "org/cocos2dx/cpp/AppActivity", "isInWifi", "()Z")) {
 jboolean ret = t.env->CallStaticBooleanMethod(t.classID, t.methodID);
 t.env->DeleteLocalRef(t.classID);
 return ret;
 }
 #endif
 }

isInWifi是一个返回boolean类型的无参函数 注意此处调用使用的是CallStaticBooleanMethod 而非CallStaticVoidMethod
返回其他类型的函数需调用相应的api

2.c++通过java调起sdk的登录支付使之在主线程运行
 使用this.runOnUiThread(......) 进行切换

 例:

 public static void start_login(){
 //将sdk登录 放到主线程中
_activity.runOnUiThread(new Runnable() {
@Override
public void run() {
_activity.login();
//login()中调起sdk登录
}
});
 }


 3.java调用c++(一般是登录或支付拿到sdk的token 向游戏服务器进行验证)
   ①新建一个java文件,定义需要使用的函数,函数声明加上native标识,表示这是一个是java调用非java函数的接口
例:这是我新建的一个wrapper.java文件
package org.cocos2dx.cpp;
public class wrapper
{
public static nativevoid nativeAnthenLogin(String token);//参数为sdk返回登录认证的token
}
②使用javah命令生成c++头文件
  javah -classpath /Users/sant/Documents/Develop/Test/proj.android/src org.cocos2dx.cpp.wrapper
  注意:classpath 只需要定位到src目录
  
  生成的头文件org_cocos2dx_cpp_wrapper.h如下:

  /* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class org_cocos2dx_cpp_wrapper */


#ifndef _Included_org_cocos2dx_cpp_wrapper
#define _Included_org_cocos2dx_cpp_wrapper
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class:     org_cocos2dx_cpp_wrapper
* Method:    nativeAnthenLogin
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_org_cocos2dx_cpp_wrapper_nativeAnthenLogin
(JNIEnv *, jclass, jstring);
#ifdef __cplusplus
}
#endif
#endif


③新建一个cpp文件实现对应的函数

#include <jni.h>
#include "org_cocos2dx_cpp_wrapper.h"


JNIEXPORT void JNICALL Java_org_cocos2dx_cpp_wrapper_nativeAnthenLogin
(JNIEnv *env, jclass, jstring jstr)
{
   //需将jstring 转换成string
char* rtn = NULL;
jclass clsstring = env->FindClass("java/lang/String");
jstring strencode = env->NewStringUTF("utf-8");
jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");
jbyteArray barr = (jbyteArray)env->CallObjectMethod(jstr, mid, strencode);
jsize alen = env->GetArrayLength(barr);
jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);
if (alen > 0)
{
rtn = (char*)malloc(alen + 1);
memcpy(rtn, ba, alen);
rtn[alen] = 0;
}
env->ReleaseByteArrayElements(barr, ba, 0);
std::string str = rtn;
CCLog("token:%s   --", str.c_str());
SDK_FUNC()->requestsss(str);
}


④以上三步搞定了以后 就可以在java文件中调用wrapper.nativeAnthenLogin(token)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值