Presentation is loading. Please wait.

Presentation is loading. Please wait.

Working with C++ Data in Java Presented by: Jessica Winblad This Presentation © 2008 Jessica Winblad.

Similar presentations


Presentation on theme: "Working with C++ Data in Java Presented by: Jessica Winblad This Presentation © 2008 Jessica Winblad."— Presentation transcript:

1 Working with C++ Data in Java Presented by: Jessica Winblad This Presentation © 2008 Jessica Winblad

2 Outline Working with C++ DLLs Working with C++ DLLs Java Native Interface (JNI) Java Native Interface (JNI) I/O with Files & Streams I/O with Files & Streams Byte/Bit Order Byte/Bit Order Data Type translation Data Type translation

3 Real World Example Powering test-equipment for 12.5 seconds Powering test-equipment for 12.5 seconds

4 Project Requirements Send voltage out a parallel port for a specified time in seconds, to a half-second accuracy Send voltage out a parallel port for a specified time in seconds, to a half-second accuracy Run on a Windows 2000 or XP machine Run on a Windows 2000 or XP machine Integrate with a test-suite already written in Java Integrate with a test-suite already written in Java

5 Engineering Challenge With Windows 98 this would have been easy With Windows 98 this would have been easy Windows 2000 provides less transparent access to the machines hardware Windows 2000 provides less transparent access to the machines hardware Only hardware device drivers can directly access the hardware Only hardware device drivers can directly access the hardware You cant write device drivers in Java You cant write device drivers in Java

6 Solution Use a device driver DLL that allows direct programming of the parallel port Use a device driver DLL that allows direct programming of the parallel port Use JNI to access the device driver Use JNI to access the device driver

7 JNI (Java Native Interface) class ioPort { public native void Out32( short PortAddress, short data); static { System.loadLibrary("jnpout32pkg");} } … ioPort pp = new ioPort(); pp.Out32(0x378, currentVal); class ioPort { public native void Out32( short PortAddress, short data); static { System.loadLibrary("jnpout32pkg");} } … ioPort pp = new ioPort(); pp.Out32(0x378, currentVal);

8 Another Real World Example

9 Byte and Bit Order Matter Big Endian (Network Byte Order) Big Endian (Network Byte Order) Eg: Motorolla 68k processor Eg: Motorolla 68k processor Little Endian Little Endian Eg: x86 PC Eg: x86 PC May need to test for endianness May need to test for endianness Java has classes to help with correcting byte order (eg: java.nio.ByteOrder ) Java has classes to help with correcting byte order (eg: java.nio.ByteOrder ) A source value of 0xFFFE = 1111 1111 1111 1110 Could be read as: 1111 1110 1111 1111 1111 1111 0111 1111 etc.

10 Converting Data Types Applies to both streams and files Applies to both streams and files If you have a double in C++ should you use a readDouble() method of your java stream/file reader to read it? (No) If you have a double in C++ should you use a readDouble() method of your java stream/file reader to read it? (No) Java and C++ do not always have the same names for equivalent primitive types. Java and C++ do not always have the same names for equivalent primitive types. Some types dont map nicely. Some types dont map nicely.

11 Size 1 byte2 bytes4 bytes8 bytes16 bytes 8 bits16 bits32 bits64 bits128 bits C++char/bool float(long) double Javabooleanchar floatdouble Size 1 byte 2 bytes 4 bytes 8 bytes 16 bytes 8 bits 16 bits 32 bits 64 bits 128 bits C++byteshortint/long long long __int128 JavabyteshortintlongBigInteger Internal Sizing of Data Types * C++ sizes are OS/compiler dependent (Win32 shown)

12 Signed/Unsigned Types Java ensures consistency by always using signed types Java ensures consistency by always using signed types C++ supports both signed & unsigned types C++ supports both signed & unsigned types Unsigned Byte Signed Byte Unsigned Short Signed Short Size 1 byte 2 bytes Value Range 0 to 255 -128 to 127 0 to 65,535 -32,768 to 32,767

13 Principle of Conversion To read in unsigned values from C++ the resulting type in Java needs to be larger To read in unsigned values from C++ the resulting type in Java needs to be larger Also, some extra conversion needs to be done to fix incorrect sign extension. Also, some extra conversion needs to be done to fix incorrect sign extension.

14 Naïve Unsigned Conversion short value = (short) in.readByte(); short value = (short) in.readByte(); Question: If a short can hold from 0 to 65,535 why doesnt this work for values 128-255? Question: If a short can hold from 0 to 65,535 why doesnt this work for values 128-255? Answer: Sign Extension applied when casting Answer: Sign Extension applied when casting

15 How Does Sign Extension Work? unsigned byte: 129 = 0x81 = 1000 0001 2 unsigned byte: 129 = 0x81 = 1000 0001 2 The sign bit is extended: 1111 1111 1000 0001 2 The sign bit is extended: 1111 1111 1000 0001 2 In twos compliment, if the sign bit = 1, the number is presumed negative. In twos compliment, if the sign bit = 1, the number is presumed negative.

16 Twos Compliment Raw Bits Signed Unsigned Raw Bits Signed Unsigned 01111111 = 127 127 01111111 = 127 127 00000010 = 2 2 00000010 = 2 2 00000001 = 1 1 00000001 = 1 1 00000000 = 0 0 00000000 = 0 0 11111111 = 1 255 11111111 = 1 255 11111110 = 2 254 11111110 = 2 254 10000001 = 127 129 10000001 = 127 129 10000000 = 128 128 10000000 = 128 128

17 Solution: Bit Masking byte b = in.readByte(); // reads as signed short bitmask = (short) 0xff; short value = (short)(b & bitmask); 1111 1111 1xxx xxxx negative 1111 1111 1xxx xxxx negative & 0000 0000 1111 1111 0xFF 0000 0000 1xxx xxxx positive 0000 0000 1xxx xxxx positive

18 Be Careful with Unsigned Ints long a = (long)(in.readInt() & 0xffffffff); long a = (long)(in.readInt() & 0xffffffff); doesnt work! doesnt work! Reason: 0xffffffff is a negative value. Reason: 0xffffffff is a negative value. Solution: Solution: long a = (long)(in.readInt() & 0xffffffffL); long a = (long)(in.readInt() & 0xffffffffL);

19 Dealing with Decimals Going from a C++ double to a Java float is easy because both are 8-byte IEEE 754 values. Going from a C++ double to a Java float is easy because both are 8-byte IEEE 754 values. Going from a C++ float to Java is harder because Java does not have a 4-byte float type Going from a C++ float to Java is harder because Java does not have a 4-byte float type But Java gives tools to make the conversion easy But Java gives tools to make the conversion easy int a = in.readInt(); float b = Float.intBitsToFloat(a); int a = in.readInt(); float b = Float.intBitsToFloat(a); out.writeInt(Float.floatBitsToInt(floatValue)); out.writeInt(Float.floatBitsToInt(floatValue));

20 Other Pitfalls & Issues If your C++ code used bit-fields, you will have to do bit masking and shifting to read out the individual fields If your C++ code used bit-fields, you will have to do bit masking and shifting to read out the individual fields Or use java.util.BitSet Or use java.util.BitSet Reading in text (Strings) – encoding matters Reading in text (Strings) – encoding matters With plain English it may not, but if you have international characters in your text, it will matter With plain English it may not, but if you have international characters in your text, it will matter InputStreamReader(InputStream in, String enc); InputStreamReader(InputStream in, String enc);

21 Questions?


Download ppt "Working with C++ Data in Java Presented by: Jessica Winblad This Presentation © 2008 Jessica Winblad."

Similar presentations


Ads by Google