문제

나는 Java UUID를 C ++로 보내려고 노력하고 있습니다. 거기서 Guid로 사용될 것입니다. 그런 다음 다시 보내서 UUID로보십시오.

쉽게 수행하는 방법에 대한 제안이 있습니까?

나는 Java에서 C ++로 보내는 복잡한 방법을 가지고 있습니다. 여기서 UUID에게 가장 적고 가장 중요한 비트를 요청하고 바이트 버퍼에 이것을 쓰고 바이트로 읽습니다.

다음은 UUID에서 2 시간을 보내고 C ++로 보내는 어리석은 방법입니다.

자바

public static byte[] asByteArray(UUID uuid) 
 {
    long msb = uuid.getMostSignificantBits();
    long lsb = uuid.getLeastSignificantBits();
    byte[] buffer = new byte[16];

    for (int i = 0; i < 8; i++) {
            buffer[i] = (byte) (msb >>> 8 * (7 - i));
    }
    for (int i = 8; i < 16; i++) {
            buffer[i] = (byte) (lsb >>> 8 * (7 - i));
    }

    return buffer;

}




    byte[] bytesOriginal = asByteArray(uuid);
    byte[] bytes = new byte[16];

    // Reverse the first 4 bytes
    bytes[0] = bytesOriginal[3];
    bytes[1] = bytesOriginal[2];
    bytes[2] = bytesOriginal[1];
    bytes[3] = bytesOriginal[0];
    // Reverse 6th and 7th
    bytes[4] = bytesOriginal[5];
    bytes[5] = bytesOriginal[4];
    // Reverse 8th and 9th
    bytes[6] = bytesOriginal[7];
    bytes[7] = bytesOriginal[6];                                 
    // Copy the rest straight up        
    for ( int i = 8; i < 16; i++ )
    {
        bytes[i] = bytesOriginal[i];
    }    

    // Use a ByteBuffer to switch our ENDIAN-ness
    java.nio.ByteBuffer buffer = java.nio.ByteBuffer.allocate(16);
    buffer.order(java.nio.ByteOrder.BIG_ENDIAN);
    buffer.put(bytes);
    buffer.order(java.nio.ByteOrder.LITTLE_ENDIAN);
    buffer.position(0);

    UUIDComponents x = new UUIDComponents();

    x.id1 = buffer.getLong();
    x.id2 = buffer.getLong();

C ++

    google::protobuf::int64 id1 = id.id1();
    google::protobuf::int64 id2 = id.id2();

    char* pGuid = (char*) &guid;
    char* pGuidLast8Bytes = pGuid + 8;
    memcpy(pGuid, &id1, 8);
    memcpy(pGuidLast8Bytes, &id2, 8);

이것은 작동하지만 너무 복잡해 보이지만 아직 다른 방향으로 작동하지 않습니다.

(저는 Google 프로토콜 버퍼를 사용하여 두 번의 오랜 시간을 보내고 있습니다)

  • 알렉스
도움이 되었습니까?

해결책

나는 무언가가 일했다.

두 번의 오랫동안 보내는 대신 바이트로 전송합니다. Java 코드는 다음과 같습니다.

public static UUID fromBytes( ByteString byteString)
{
    byte[] bytesOriginal = byteString.toByteArray();
    byte[] bytes = new byte[16];

    // Reverse the first 4 bytes
    bytes[0] = bytesOriginal[3];
    bytes[1] = bytesOriginal[2];
    bytes[2] = bytesOriginal[1];
    bytes[3] = bytesOriginal[0];
    // Reverse 6th and 7th
    bytes[4] = bytesOriginal[5];
    bytes[5] = bytesOriginal[4];
    // Reverse 8th and 9th
    bytes[6] = bytesOriginal[7];
    bytes[7] = bytesOriginal[6];                                 
    // Copy the rest straight up        
    for ( int i = 8; i < 16; i++ )
    {
        bytes[i] = bytesOriginal[i];
    }    

    return toUUID(bytes);
}

public static ByteString toBytes( UUID uuid )
{
    byte[] bytesOriginal = asByteArray(uuid);
    byte[] bytes = new byte[16];

    // Reverse the first 4 bytes
    bytes[0] = bytesOriginal[3];
    bytes[1] = bytesOriginal[2];
    bytes[2] = bytesOriginal[1];
    bytes[3] = bytesOriginal[0];
    // Reverse 6th and 7th
    bytes[4] = bytesOriginal[5];
    bytes[5] = bytesOriginal[4];
    // Reverse 8th and 9th
    bytes[6] = bytesOriginal[7];
    bytes[7] = bytesOriginal[6];                                 
    // Copy the rest straight up        
    for ( int i = 8; i < 16; i++ )
    {
        bytes[i] = bytesOriginal[i];
    }    

    return ByteString.copyFrom(bytes);
}


private static byte[] asByteArray(UUID uuid) 
 {
    long msb = uuid.getMostSignificantBits();
    long lsb = uuid.getLeastSignificantBits();
    byte[] buffer = new byte[16];

    for (int i = 0; i < 8; i++) {
            buffer[i] = (byte) (msb >>> 8 * (7 - i));
    }
    for (int i = 8; i < 16; i++) {
            buffer[i] = (byte) (lsb >>> 8 * (7 - i));
    }

    return buffer;

}

private static UUID toUUID(byte[] byteArray) {

    long msb = 0;
    long lsb = 0;
    for (int i = 0; i < 8; i++)
            msb = (msb << 8) | (byteArray[i] & 0xff);
    for (int i = 8; i < 16; i++)
            lsb = (lsb << 8) | (byteArray[i] & 0xff);
    UUID result = new UUID(msb, lsb);

    return result;
}

이렇게하면 바이트를 C ++ 측에서 똑바로 사용할 수 있습니다. 바이트 순서의 전환을 수행 할 수 있다고 생각합니다. 어느 하나 끝.

C ++

    memcpy(&guid, data, 16);

다른 팁

사용하기가 가장 쉽습니다 getMostSignificantBits 그리고 getLeastSignificant 얻을 수있는 비트 long 가치를 보내십시오. 마찬가지로 적절한 생성자를 사용하여 두 시간 동안 UUID를 재구성 할 수 있습니다.

부끄러운 일이 없습니다 toByteArray/fromByteArray 방법 쌍 :(

당신의 현재 방식은 괜찮습니다. 그런 식으로하는 것에 대해 잘못된 것은 없습니다. 또 다른 적절성은 uuid의 문자열 표현과 통신하고 문자열을 보내고 C ++로 구문 분석하는 것입니다.

BTW, 바이트는 바이트/숯 어레이를 주조하거나 정수 유형과 유사하지 않으면 바이트를 적절한 순서로 다시 할당하여 endianess를 결정하지 않는 한 endianess가 없습니다.

C ++ Guid를 Java UUID로 변환하기 위해 내가하는 일은 다음과 같습니다. C ++ 측에서 Guid Struct는 바이트로 변환됩니다. C ++로의 변환은 같은 줄을 따라 갈 수 있습니다.

public static UUID cppGuidBytesToUuid(byte[] cppGuid) {
    ByteBuffer b = ByteBuffer.wrap(cppGuid);
    b.order(ByteOrder.LITTLE_ENDIAN);
    java.nio.ByteBuffer out = java.nio.ByteBuffer.allocate(16);
    out.order(ByteOrder.BIG_ENDIAN);
    out.putInt(b.getInt());
    out.putShort(b.getShort());
    out.putShort(b.getShort());
    out.put(b);
    out.position(0);
    return new UUID(out.getLong(), out.getLong());
}


// Here is the JNI code ;-)
jbyteArray GUID2ByteArray(JNIEnv *env,GUID* guid)
{
    if (guid == NULL)
    return NULL;
    jbyteArray jGUID = env->NewByteArray(sizeof(GUID));
    if (jGUID == NULL)
    return NULL;
    env->SetByteArrayRegion(jGUID,0,sizeof(GUID),(signed char*)(guid));
    if (env->ExceptionOccurred() != NULL)
    return NULL;
    return jGUID;
}

아마도 당신은 왜 당신이 단순히하지 않는지 설명 할 수 있습니다.

UUID uuid = 
x.id1 = uuid.getMostSignificantBits();
x.id2 = uuid.getLeastSignificantBits();

추신 : @jon Skeet의 게시물을 다시 읽으면 이것이 거의 같은 조언이라고 생각합니다. ;)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top