Pio*_*ler 6 c++ java sockets double struct
假设已经编写了不可更改的宿主程序,它通过socket接收这样的C++结构:
#pragma pack(push, 2)
struct Data {
double x;
double y;
double z;
long frameNumber;
};
#pragma pack(pop)
Run Code Online (Sandbox Code Playgroud)
平台:在Visual Studio 2008中编译的C++/32位Windows应用程序
如何从Java Socket发送这样的数据?我已经注意用putDouble()填充ByteBuffer,putLong(),putInt()假设长达32位,但我无法生成有效值.
我也随机生成和发送数据,并且结构级别的字节赋值看起来很好(我只能随机化一个值,例如X),但我不能产生精确的值(可能是不同的双重表示?),而只是通过发送随机的东西Math.random()*Double.MAX_VALUE;
我是否可以仅在一方(产生数据的客户端)上使用Google Protocol Buffers来解决此问题?
记住,我无法改变服务器(接收)方面
我知道我可以将数据发送到C++并使用JNI,但我正在寻找更简单的解决方案.
我在这里看到至少2个可能的问题:
这些东西在C++中用Java看起来是什么样的?
几个小时后,我将提供"字节黑客"的精确样本数据(发送前的确切Java值和C++中收到的double的值)
关于服务器坏设计回答
我知道这样的实现和不可更改的服务器是坏软件,但这个问题的环境是在"hobbistic-level"向小型旧应用程序注入一些数据
Java表示
也许这会对某些位级C++专家有所帮助:
Long.toBinaryString( Double.doubleToRawLongBits( (double) 0 ) );
// 000000000000000000000000000000000000000000000000000000000000000
Long.toBinaryString( Double.doubleToRawLongBits( 1 ) );
// 011111111110000000000000000000000000000000000000000000000000000
Long.toBinaryString( Double.doubleToRawLongBits( 1.1 ) );
// 011111111110001100110011001100110011001100110011001100110011010
Long.toBinaryString( Double.doubleToRawLongBits( 1024 ) );
// 100000010010000000000000000000000000000000000000000000000000000
Long.toBinaryString( Double.doubleToRawLongBits( 1024.1024 ) );
// 100000010010000000000000110100011011011100010111010110001110001
Long.toBinaryString( Double.doubleToRawLongBits( Double.MAX_VALUE ) );
// 111111111101111111111111111111111111111111111111111111111111111
Run Code Online (Sandbox Code Playgroud)
我想到了。Int 值发送得很好(可能无法在主机程序中 100% 确定地检查这一点),问题出在双字节字节序上。您需要在发送之前转换双精度数:
public static double changeEndian( double x ) {
ByteBuffer cv = ByteBuffer.allocate( 8 ).putDouble( x );
cv.order( ByteOrder.LITTLE_ENDIAN );
cv.rewind();
return cv.getDouble();
}
Run Code Online (Sandbox Code Playgroud)
并将 ByteBufer 与 putDouble()/putInt() 一起使用。