Mixed-Language Programming


Exchanging Data between Java and C/C++ Windows Programs

Dr. He Lingsong

The notorious "endian" problem shows up in all sorts of places — in this case, between different programming languages.


Introduction

Under the Windows operating system, Java and C/C++ programs use different formats for storing data in memory. For example, in C/C++ programs built for Windows, a short integer consists of two bytes; the low byte is stored at a lower address than the high byte. This is called "little-endian" format. In contrast, Java programs always store a short integer with the high byte at the low address, followed by the low byte. This is called "big-endian" format.

Java uses this big-endian format regardless of platform or OS, but C and C++ use the format dictated by the OS. Thus, it is impossible to directly exchange binary data and binary data files between Java and C/C++ programs that run in Windows. (On most Unix systems data interchange is not a problem, because most Unix systems use big-endian format.)

Using the technique of I/O stream redirection in Java, I have designed a Java class to translate data from the C/C++ format to the Java format. This class enables Java programs to receive and read data files written by C/C++ programs. Interested readers may want to use similar techniques to enable transfers in the other direction — from Java to C/C++.

The Data Translation Class

The data translation class, WindowsStream, uses a very simple technique to translate data from little-endian format to big-endian. First, it reads a multi-byte data type, byte-by-byte, to a buffer. Then it reverses the byte order in the buffer. The source code is shown in Listing 1.

Applications

Reading Data Files Produced by C/C++ Programs

Java and C/C++ use the same respective data formats when writing to data files as they do when storing data in memory. Therefore, a Java program can’t directly read binary data from file created by a C/C++ program (under Windows).

The following example shows how to use the WindowsStream class introduced above to solve this problem. In this example, the Java program reads a Windows .WAV file that was created in the C/C++ data store format. The .WAV file has the following structure:

char r[4];        //4 bytes
long int fs;      //4 bytes
char w[8];        //8 bytes
long int hs;      //4 bytes
short int p, ch;  //2 bytes+2 bytes
long int hz, bhz; //4 bytes+4 bytes
short int b, bit; //2 bytes+2 bytes
char d[4];        //4 bytes
long int ds;      //4 bytes
char *wave;       //ds bytes

In this format, ch is the channel number used for recording; hz is the sampling frequency, bit is the number of bits used by the analog to digital converter; ds is the size of the file; and wave is a pointer to the data. The other parameters are shown just for reference. This example assumes that the long int type is four bytes long in C/C++ and eight bytes long in Java.

Listing 2 shows the Java class WavFile, which uses the WindowsStream class to read the .WAV file correctly. Class WavFile supplies a read method to read the Windows .WAV file. The parameter location is the Internet address of the .WAV file; buffer is a temporary buffer that is used to store the raw data; ch1 and ch2 are the data buffers used to store the corrected data for the left and right channels respectively; and par is a temporary buffer used to store the corrected parameters of the .WAV file. The snippet below shows a sample use of class WavFile to read a .WAV file into a Java program.

int ch=0, len=0, fre=0, bit=0;
short x1[] = new short[16385];
short x2[] = new short[16385];
byte buffer[] = new byte[64540];
int par[] = new int[5];
String url = "http://127.0.0.1/ding.wav";
WavFile hl = new WavFile();
...
hl.read(url, buffer, x1, x2, 16384, par);
ch=par[0];
fre=par[1];
len=par[2];
bit=par[3];  
...

Receiving Data Directly from C/C++ Programs

In this example, a Windows-based C++ UDP (User Datagram Protocol) server produces a set of data which is received by a Java UDP client. The server program samples a 100 Hz sine wave at 11,025 Hz, stores the data in an array of short integers, and creates a UDP server socket on port 8888 to wait for the client’s request for data. When the client sends any data to port 8888, the server sends back the sine wave data. The server program is not shown here, but is available on the CUJ website (www.cuj.com/code/). It uses the freeware TCP4U package [2] to supply TCP/IP functionality.

To receive data from the UDP server program, the Java program uses a class named UdpData (Listing 3). This class sends a UDP command to the server and receives the returned data; then it calls the class WindowsStream to translate data from the C/C++ format to the Java format.

Class UdpData also supplies a read method. The parameter host is the IP address of the computer running the UDP server program; buffer is the temporary data buffer that is used to store raw data; ch1 is the data buffer that is used to store the corrected data of the sine wave. The snippet below uses class UdpData to get data from the UDP server program.

...
String host = "127.0.0.1";
UdpData udphl = new UdpData();
...
udphl.read(host, buffer, x1);
ch=1;
fre=11025;
len=1024;
bit=16;  
...

A Java Demo Applet

The last example is a Java applet that reads a Windows .WAV file, receives data from the UDP server program, and draws the signal waveform, as shown in Figure 1. Pressing the buttons labeled "Ding" and "Chord" causes the applet to read the files Ding.wav and Chord.wav respectively. Pressing the button labeled "UDP" causes the applet to get the sine-wave data from the UDP server program. The applet source code is shown in Listing 4.

References

[1] "Big and Little Endian Byte Orderings," http://www.carmel.com/pmon/pmon5/html/endian.htm

[2] Philippe Jounin and Laurent Le Bras. TCP4U API — User Manual, http://membres.tripod.fr/phjounin/P_tcp4u.htm.

Dr. He Lingsong is an Associate Professor at the Huazhong University of Science and Technology in China, and an experienced C/C++ and Java programmer. One of his shareware programs, Signal Analyze Toolkit, gets five stars at www.zdnet.com. You can reach Dr. Lingsong at http://heliso.tripod.com or heliso@public.wuhan.cngb.com.