I am trying to convert c to java but I am having difficult to convert c data types to java. This program reads a binary file and stores it in a common_block. The common_block is defined below.
Now I convert it into Java as such:
But when I try to read the binary file using DataInpuStream it does not come out correctly. Only type, key, and id were retrieved correctly. All other values do not match. Can someone points out what I am doing wrong?
I'm not sure how the data types are stored in C, but the first thing that I notice is that you're using floats in Java where you had doubles in C. Shouldn't it be a double in Java as well? If you've got a variable of the wrong size it would explain why you'd get different results - not only would you get the wrong value for that variable but you'd get the wrong value for every following variable as well. I'm guessing that type, key, and id are the first three fields that are read?
Once you've got variables of the right size, you may still find some aren't right. It depends on the storage format of the variables - it wouldn't surprise me at all (but I don't know for sure) if C used a different floating point format to Java. If so, for those items you may need to fiddle about with the bits directly to get the right values.
[Moving to Java in General, because this isn't really a beginner's topic]
Matthew Brown wrote:I'm not sure how the data types are stored in C
For example, widths are not mandated. All that matters in terms of size of a given type is something like short <= int <= long.
So depending on which compiler, hardware, and OS you use, you might end up with them being the same size as in Java, or you might end up with short, int, and long all 2 bytes, or you might end up with them all being 8 bytes, or various combinations in between.
DataInputStream and DataOutputStream are for reading and writing binary data in Java's serialization format. That format is not a straightforward binary dump of the variables in exactly the way as the struct would be laid out in memory in C.
So if you have some binary file in which the struct is stored in a C memory layout, it is not going to be possible to read it with DataInputStream in Java. Instead, you would have to use a normal FileInputStream and read it byte by byte, and assemble the data in your Java program.
Thank you all for your prompt reply. I found out what's happening. It's like Jeff stated, it has to do with the hardware and OS. This program was written for UNIX and now I am working in Windows 7 64-bit. The machine bit architecture are different on each platform. It's high-order vs low-order bits. I appreciate all your comments.
bruce truong wrote:Thank you all for your prompt reply. I found out what's happening. It's like Jeff stated, it has to do with the hardware and OS. This program was written for UNIX and now I am working in Windows 7 64-bit. The machine bit architecture are different on each platform. It's high-order vs low-order bits. I appreciate all your comments.
Take a look at the java.nio.ByteBuffer class. It has methods for various datatypes of various sizes -- along with handling of bit ordering (Big versus little Endian).
Joined: Mar 14, 2011
I implemented it using Integer.reverseBytes() and it works fine. ByteBuffer class is too complicated for me but I will keep that suggestion in mind.
1) The size of long and int is not specified in C. An int can be 16 bits, or 32 bits, or possibly even 64 bits. A long can be 32 bits but also 64 bits.
2) You were already told about the double -> float issue.
3) A char in C is only one byte, whereas a char in Java is two. The best match would be Java's byte.
4) C has no data type for strings. A char is not a string. It's just a number of chars that together can be interpreted as a string, but it's still not one. A similar statement can be made about char*. The closest match to your char is a byte of size 6.
My advice - use JNA with its data type mapping that is guaranteed to work.
Rob Spoor wrote:1) The size of long and int is not specified in C. An int can be 16 bits, or 32 bits, or possibly even 64 bits. A long can be 32 bits but also 64 bits.
Right. Long ago, an int was often 16 bits, because we used 16 bit computers. In the 1980s, even PCs had 32 bit processors (80386) which had, 32 bit ints.
These days, all desktop and server computers are 64 bit, so "int" is now often 64-bit. Its an "implementation detail" to the compiler, so you never can make assumptions.
All of the excitement in the C world is in embedded systems, using PIC, ARM, ATMEL, and other CPUs (often microcontrollers). They often use smaller data paths, but even there, the newer stuff uses longer words.