3

Java UUID を C++ に送信しようとしており、そこで GUID として使用され、それを返送して UUID として表示されます。それをわずか 16 バイトとして送信したいと考えています。

これを行う簡単な方法に関する提案はありますか?

Java から C++ に送信する複雑な方法があります。UUID に最下位ビットと最上位ビットを要求し、これを ByteBuffer に書き込み、バイトとして読み取ります。

これは、UUID から 2 つの long を取得し、それらを 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 プロトコル バッファを使用して、2 つの long を前後に送信しています)

  • アレックス
4

5 に答える 5

1

これが、C++GUIDをJavaUUIDに変換するために私が行うことです。C ++側では、GUID構造体はバイトに変換されるだけです。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;
}
于 2010-02-10T12:06:02.740 に答える
1

ビットを使用して値を取得getMostSignificantBitsし、それらを送信するのがおそらく最も簡単です。同様に、適切なコンストラクターを使用して、これら 2 つの long から UUID を再構築できます。getLeastSignificantlong

toByteArray/fromByteArrayペアのメソッドがないのは残念です:(

于 2009-06-28T18:16:38.893 に答える
1

あなたの現在の方法は問題ありません。そのようにすることは何も悪いことではありません。別のアプローチは、uuid の文字列表現と通信し、文字列を送信し、C++ で解析することです。

ところで、バイトにはエンディアンがありません。バイト/文字配列または整数型に類似したものをキャストしない限り、適切な順序でバイトを割り当てることによってエンディアンを決定するだけです。

于 2009-06-28T19:34:22.727 に答える
0

たぶん、あなたがただしていない理由を説明できるでしょう。

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

PS @Jon Skeet の投稿をもう一度読んだとき、これはほとんど同じアドバイスだと思います。;)

于 2009-06-28T18:54:17.270 に答える