我正在使用 Google Play Services 和 Cocos2d-x 开发多人游戏。我已经使用 设置了 Java 和 C++ 之间的通信JNI
,并且可以运行诸如登录、创建房间、邀请之类的过程……一切都很好,直到我需要将一些发送struct
给其他玩家。从其他人接收数据时,发生错误。这是结构:
typedef enum
{
MESSAGE_TYPE_PING = -1,
MESSAGE_TYPE_PING_BACK = 0,
MESSAGE_TYPE_RTT = 3
} MESSAGE_TYPE;
typedef struct
{
MESSAGE_TYPE messType;
} MESSAGE;
typedef struct
{
MESSAGE mess;
timeval sendTime;
const char* text;
} PING_MESSAGE;
在此代码段中,我将其转换struct
并发送给其他玩家:
void MyClass::sendData()
{
// Send package
PING_MESSAGE ping;
ping.mess.messType = MESSAGE_TYPE_PING;
ping.sendTime = startTime;
ping.text = "Ohhhhhh";
char byte[sizeof(ping)];
memcpy(byte, &ping, sizeof(ping));
GCHelper::sendReliableRealTimeMessage(&byte[0]);
}
// In GCHelper's implementation
void GCHelper::sendReliableRealTimeMessage(const char* byteMess)
{
// Convert char* to jbyteArray
jbyteArray bArray = env->NewByteArray(16); //env is a static JNIEnv* in this class; 16 since my PING_MESSAGE struct is 16 bytes in size;
env->SetByteArrayRegion(bArray,0,16,(jbyte*)byteMess);
// Make Java call
env->CallStaticVoidMethod(classID, methodID, bArray);
methodInfo.env->DeleteLocalRef(bArray);
methodInfo.env->DeleteLocalRef(classID);
}
现在,Java 代码负责将字节数组发送给房间中的参与者。在接收方,我继续将接收到的数据发送到 C++。当我转换jbyteArray
回struct
:
void Java_package_name_TestMulti_nativeOnRealTimeMessageReceived(JNIEnv *env, jobject thiz, jbyteArray receivedMess)
{
CCLOG("Called from java");
jboolean isCopy;
jbyte * pCData = env->GetByteArrayElements(receivedMess, &isCopy);
jsize size = env->GetArrayLength(receivedMess);
const char* sd = (const char*)pCData;
PING_MESSAGE result;
memcpy(&result, sd, sizeof(result));
CCLOG("TEST size: %d", size); // This log out: "TEST size: 16"
CCLOG("TEST type: %d", result.mess.messType); // This log out: "TEST type: -1"
CCLOG("TEST text: %s", result.text); // AND ERROR!!!!!!!
cocos2d::CCByteArray* data = cocos2d::CCByteArray::createWithData(sd);
cocos2d::CCNotificationCenter::sharedNotificationCenter()->postNotification("onRealTimeMessageReceived", data);
if(isCopy)
{
env->ReleaseByteArrayElements(receivedMess,pCData,JNI_ABORT);
}
}
我不明白这里。如果我不向其他玩家发送字节数组,但通过nativeOnRealTimeMessageReceived()
从 Java 端调用方法将该数组发送回 C++,它运行良好并正确记录。这意味着对于从 C++byte[]
转换而来的相同包char*
,如果我只是将其传递回 C++,它是正确的,但如果我通过 Google Play 游戏服务发送它,它就会出错。这是什么意思?