将 Java UUID 发送到 C++ 作为字节并通过 TCP 返回
我正在尝试将 Java UUID 发送到 C++,在那里它将用作 GUID,然后将其发送回来并将其视为 UUID,我希望将其发送为仅 16 个字节。
关于一个简单的方法来做到这一点有什么建议吗?
我有一种复杂的方法来做到这一点,从 Java 发送到 C++,其中我询问 UUID 的最低和最高有效位,将其写入 ByteBuffer,然后将其作为字节读出。
这是我从 UUID 中获取 2 个 long 并将它们发送到 C++ 的愚蠢而复杂的方法:
Java
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);
这可行,但似乎太复杂了,而且我还无法让它在另一个方向上工作。
(我正在使用谷歌协议缓冲区来回发送两个长整型)
- 亚历克斯
I'm trying to send a Java UUID to C++, where it will be used as a GUID, then send it back and see it as a UUID, and I'm hoping to send it across as just 16 bytes.
Any suggestions on an easy way to do this?
I've got a complicated way of doing it, sending from Java to C++, where I ask the UUID for its least and most significant bits, write this into a ByteBuffer, and then read it out as bytes.
Here is my silly-complicated way of getting 2 longs out of a UUID, sending them to C++:
Java
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);
This works, but seems way too complex, and I can't yet get it working in the other direction.
(I'm using google protocol buffers to send the two longs back and forth)
- Alex
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我有一些工作。
我不是将其作为两个长整型发送,而是将其作为字节发送,这是 Java 代码:
这样做,字节可以直接在 C++ 端使用。 我想字节顺序的切换可以在任一端完成。
C++
I got something working.
Instead of sending it across as two longs, I send it across as bytes, here is the Java code:
Doing it this way, the bytes can be used straight up on the C++ side. I suppose the switching around of the order of the bytes could be done on either end.
C++
使用
getMostSignificantBits
和getLeastSignificant
位来获取long
值并发送这些值可能是最简单的。 同样,您可以使用适当的构造函数从这两个 long 重建 UUID。遗憾的是没有
toByteArray
/fromByteArray
对方法:(It's possibly easiest to use
getMostSignificantBits
andgetLeastSignificant
bits to getlong
values, and send those. Likewise you can reconstruct the UUID from those two longs using the appropriate constructor.It's a shame there isn't a
toByteArray
/fromByteArray
pair of methods :(你现在的做法没问题,这样做并没有什么问题。
另一种方法是与 uuid 的字符串表示形式进行通信,发送字符串,在 C++ 中解析它。
顺便说一句,字节没有字节顺序,除非您要转换字节/字符数组或类似于整数类型,否则您只需通过按适当的顺序分配字节来确定字节顺序。
Your current way is fine, nothing wrong about doing it that way.
Another approace is yo just communicate with the string representation of the uuid, send the string, parse it in c++.
Btw, bytes do not have endianess, Unless you're casting a byte/char array or similar to an integer type, you just determine the endianess by assigning the bytes back in the approprate order.
以下是将 C++ GUID 转换为 Java UUID 的操作。 在 C++ 方面,GUID 结构只是转换为字节。 到 C++ 的转换可以按照同样的思路进行。
Here is what I do to convert a C++ GUID to a Java UUID. On the C++ side, the GUID struct is just converted to bytes. The conversion to C++ can then just go along the same lines.
也许你可以解释为什么你不只是做。
PS 当我再次阅读@Jon Skeet 的帖子时,我认为这是同样的建议。 ;)
Perhaps you could explain why you are not just doing.
P.S. As I read @Jon Skeet's post again, I think this is much the same advice. ;)