2

我正在使用 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++。当我转换jbyteArraystruct

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 游戏服务发送它,它就会出错。这是什么意思?

4

0 回答 0