View
217
Download
0
Category
Tags:
Preview:
Citation preview
Working with C+Working with C++ Data in Java+ Data in Java
Presented by: Presented by: Jessica WinbladJessica Winblad
This Presentation © 2008 Jessica Winblad
OutlineOutline
Working with C++ DLLsWorking with C++ DLLs Java Native Interface (JNI)Java Native Interface (JNI)
I/O with Files & StreamsI/O with Files & Streams Byte/Bit OrderByte/Bit Order Data Type translationData Type translation
Real World ExampleReal World Example
Powering test-equipment for 12.5 Powering test-equipment for 12.5 secondsseconds
Project RequirementsProject Requirements
Send voltage out a parallel port for a Send voltage out a parallel port for a specified time in seconds, to a half-specified time in seconds, to a half-second accuracysecond accuracy
Run on a Windows 2000 or XP Run on a Windows 2000 or XP machinemachine
Integrate with a test-suite already Integrate with a test-suite already written in Javawritten in Java
Engineering ChallengeEngineering Challenge
With Windows 98 this would have With Windows 98 this would have been easybeen easy
Windows 2000 provides less Windows 2000 provides less transparent access to the machine’s transparent access to the machine’s hardwarehardware Only hardware device drivers can Only hardware device drivers can
directly access the hardwaredirectly access the hardware You can’t write device drivers in JavaYou can’t write device drivers in Java
SolutionSolution
Use a device driver DLL that allows Use a device driver DLL that allows direct programming of the parallel direct programming of the parallel portport
Use JNI to access the device driverUse JNI to access the device driver
JNI (Java Native JNI (Java Native Interface)Interface)
class ioPort {class ioPort { public public nativenative void Out32( void Out32( short PortAddress, short data); short PortAddress, short data); static static { { System.loadLibrarySystem.loadLibrary("jnpout32pkg");}("jnpout32pkg");}}}……ioPort pp = new ioPort();ioPort pp = new ioPort();pp.Out32(0x378, currentVal);pp.Out32(0x378, currentVal);
Another Real World Another Real World ExampleExample
Byte and Bit Order Byte and Bit Order MatterMatter
Big Endian (“Network Byte Order”)Big Endian (“Network Byte Order”) Eg: Eg: Motorolla 68k processorMotorolla 68k processor
Little Endian Little Endian Eg: Eg: x86 PCx86 PC
May need to test for May need to test for “endianness” “endianness”
Java has classes to help with Java has classes to help with correcting byte order correcting byte order (eg: (eg: java.nio.ByteOrderjava.nio.ByteOrder ) )
A source value of A source value of 0xFFFE = 0xFFFE = 1111 1111 1111 11101111 1111 1111 1110 Could be read as:Could be read as: 1111 1110 1111 1111 1111 1110 1111 1111 1111 1111 0111 11111111 1111 0111 1111 etc.etc.
Converting Data TypesConverting Data Types
Applies to both streams and filesApplies to both streams and files If you have a double in C++ should you If you have a double in C++ should you
use a readDouble() method of your java use a readDouble() method of your java stream/file reader to read it? stream/file reader to read it? (No)(No)
Java and C++ do not always have the Java and C++ do not always have the same names for equivalent primitive same names for equivalent primitive types. types.
Some types don’t map nicely.Some types don’t map nicely.
Size
1 byte 2
bytes
4 bytes
8 bytes 16 bytes
8 bits 16
bits 32
bits 64 bits 128 bits
C++
char/bool
float(long) double
Java
boolean char float double
SizSizee
1 byte 1 byte 2 2 bytes bytes
4 bytes 4 bytes 8 bytes 8 bytes 16 bytes 16 bytes
8 bits 8 bits 16 16 bits bits
32 bits 32 bits 64 bits 64 bits 128 bits 128 bits
C+C+++
bytebyte shortshort int/longint/long long long longlong
__int128__int128
JavJavaa
bytebyte shortshort intint longlong BigIntegerBigInteger
Internal Sizing of Data Internal Sizing of Data TypesTypes
* C++ sizes are OS/compiler dependent (Win32 shown)* C++ sizes are OS/compiler dependent (Win32 shown)
Signed/Unsigned TypesSigned/Unsigned Types Java ensures consistency by always using Java ensures consistency by always using
signed types signed types C++ supports both signed & unsigned typesC++ supports both signed & unsigned types
UnsignUnsigned Byteed Byte
SigneSigned d
ByteByte
UnsigneUnsigned Shortd Short
Signed Signed ShortShort
SizeSize 1 byte1 byte 1 byte1 byte 2 bytes2 bytes 2 bytes2 bytes
ValuValue e RangRangee
0 to 2550 to 255 -128 -128 to 127to 127
0 to 0 to 65,53565,535
-32,768 -32,768 to 32,767to 32,767
Principle of ConversionPrinciple of Conversion
To read in To read in unsigned valuesunsigned values from from C++C++ the resulting type in the resulting type in JavaJava needs to be needs to be largerlarger
Also, some extra conversion needs to Also, some extra conversion needs to be done to fix incorrect sign be done to fix incorrect sign extension.extension.
Naïve Unsigned Naïve Unsigned ConversionConversion
short value = (short) in.readByte();short value = (short) in.readByte();
Question:Question: If a short can hold from 0 If a short can hold from 0 to 65,535 why doesn’t this work for to 65,535 why doesn’t this work for values 128-255?values 128-255?
Answer:Answer: Sign Extension applied Sign Extension applied when castingwhen casting
How Does Sign Extension How Does Sign Extension Work?Work?
unsigned byte: 129 = 0x81 = unsigned byte: 129 = 0x81 = 11000 000 0001000122
The sign bit is extended: The sign bit is extended: 1111 11111111 1111 11000 0001000 000122
In twos compliment, if the sign bit = In twos compliment, if the sign bit = 1, the number is presumed negative.1, the number is presumed negative.
Twos ComplimentTwos Compliment
Raw BitsRaw Bits SignedSigned UnsignedUnsigned 001111111 = 127 1271111111 = 127 127 000000010 = 2 20000010 = 2 2 000000001 = 1 10000001 = 1 1 000000000 = 0 00000000 = 0 0 111111111 = −1 2551111111 = −1 255 111111110 = −2 2541111110 = −2 254 110000001 = −127 1290000001 = −127 129 110000000 = −128 1280000000 = −128 128
Solution: Bit MaskingSolution: Bit Masking
byte b = in.readByte(); // reads as byte b = in.readByte(); // reads as signedsigned
short bitmask = (short) 0xff;short bitmask = (short) 0xff;
short value = (short)(b & bitmask);short value = (short)(b & bitmask);
11111 1111 1xxx xxxx negative111 1111 1xxx xxxx negative
& 0000 0000 1111 1111& 0000 0000 1111 1111 0xFF 0xFF
00000 0000 1xxx xxxx positive000 0000 1xxx xxxx positive
Be Careful with Be Careful with Unsigned IntsUnsigned Ints
long a = (long)(in.readInt() & long a = (long)(in.readInt() & 0xffffffff);0xffffffff); doesn’t work!doesn’t work!
Reason:Reason: 0xffffffff is a 0xffffffff is a negativenegative value. value.
Solution: Solution: long a = (long)(in.readInt() & long a = (long)(in.readInt() &
0xffffffff0xffffffffLL););
Dealing with DecimalsDealing with Decimals
Going from a C++ double to a Java float is Going from a C++ double to a Java float is easy because both are 8-byte IEEE 754 values. easy because both are 8-byte IEEE 754 values.
Going from a C++ float to Java is harder Going from a C++ float to Java is harder because Java does not have a 4-byte float type because Java does not have a 4-byte float type
But Java gives tools to make the conversion But Java gives tools to make the conversion easyeasy
int a = in.readInt(); int a = in.readInt(); float b = Float.intBitsToFloat(a);float b = Float.intBitsToFloat(a);
out.writeInt(Float.floatBitsToInt(floatValue)); out.writeInt(Float.floatBitsToInt(floatValue));
Other Pitfalls & IssuesOther Pitfalls & Issues
If your C++ code used bit-fields, you will If your C++ code used bit-fields, you will have to do bit masking and shifting to read have to do bit masking and shifting to read out the individual fieldsout the individual fields Or use java.util.BitSetOr use java.util.BitSet
Reading in text (Strings) – encoding Reading in text (Strings) – encoding mattersmatters With “plain English” it may not, but if you have With “plain English” it may not, but if you have
international characters in your text, it will international characters in your text, it will mattermatter
InputStreamReader(InputStream in, String InputStreamReader(InputStream in, String enc);enc);
Questions?Questions?
Recommended