-1

I have problem with conversion of C++ integer to Java int.

In c++:

//while loop
int *bla = new int; *bla = counter; //counter starting from 0
counter++;
if ((size = send(client, bla, 4, 0)) == -1) //sizeof(int) show 4 bytes so I put it there directly
{
       cerr << "Error." << endl;
       return -1;
}

In Java:

//while loop
//DataInputStream inFromServer;
System.out.println(inFromServer.readInt()); //it should read 4 bytes and interpret it as int

Result from Java:

0        //for 0
16777216 //for 1
33554432 //for 2
50331648 //etc.
67108864
83886080
100663296
117440512
134217728
150994944
167772160
184549376
201326592
218103808
234881024
251658240

(I'm using g++)

EDIT: Both (java and c++ app) runs on the same Raspberry Pi with Raspian OS (so it's localhost)

Jurass
  • 435
  • 1
  • 5
  • 17
  • Your C++-code is buggy. First fix the memory problems and the send-check – deviantfan Mar 27 '14 at 21:25
  • Don't forget to mark an answer as the solution if it solved your issue. Also it would probably be good to seek what is flipping the endianness of your data to begin with to avoid future issues. – Peter Clark Mar 27 '14 at 23:12
  • Just ran across [this link](http://stackoverflow.com/questions/13211770/endianness-on-datainputstream) stating that DataInputStream is big endian **ONLY** (meaning it converts data if needed automatically), which would be an issue if your machine is little endian (which [according to this](http://raspberrypi.stackexchange.com/questions/7279/big-endian-distribution-for-the-raspberry-pi) the Raspberry pi is). Thought of this post when I saw it. – Peter Clark Mar 29 '14 at 04:28

2 Answers2

4

It appears that you are running into endianness differences between your client and server machine (assuming you're running c++ on one and java on the other). Endianness determines the order that bytes are read by the cpu. For example, if you have the number 1, it can be stored as a 32-bit integer (4 bytes) as either 0x 00 00 00 01 (big endian) or 0x 01 00 00 00 (little endian). This explains why you get 16777216 for the value 1, as 0x01000000 == 16777216. The issue is that different hardware doesn't agree on a single endianness for numerous reasons.

For handling endianness over the network (or possibly in other situations as well), you generally convert from host endianness to network endianness (which is agreed upon) on the sender, then from network endianness to host endianness on the receiver.

There are other possible issues with the code you provided, but this appears to be why your numbers come out as what they do on the server.


EDIT

You mention in your edit that you're running on the same machine. Endianness could still be the issue; it's possible you're doing only one side of the conversion between host and network endianness, though it doesn't look like it at first glance. I'm not familiar with java, but looking at the documentation I don't see any mention if it auto converting what is read.

Community
  • 1
  • 1
Peter Clark
  • 2,863
  • 3
  • 23
  • 37
2

The results you're getting are:

0x01000000
0x02000000
0x03000000

etc.

I wonder if this is a big-endian vs. little-endian problem.... Can you try sending a known value in the counter so we can verify this? For example, if you send 1144201745 (=0x44332211) and get 287454020 (=0x11223344), that would be a good test.

jwismar
  • 12,164
  • 3
  • 32
  • 44
  • Or: Just try [reverseBytes()](http://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#reverseBytes%28int%29); if that does the trick you have an endianness issue. – JimmyB Mar 27 '14 at 21:27
  • @jwismar: Yes, it is: http://stackoverflow.com/questions/9385542/java-datainputstream-readint-from-c-client-getting-huge-value – deviantfan Mar 27 '14 at 21:28
  • Yes it works as you said: send 1144201745 appears as 287454020. Thanks for help. – Jurass Mar 27 '14 at 21:42