"Chris" <> wrote in message
news: om...
> "Chris Uppal" <> wrote in message
news:<Xe6dnQCB2pmbXBbcRVn->...
> > Chris wrote:
> >
> > > [...] legacy systems that implement
> > > messages as C Structs many of which use C bit notation ( message
> > > fields may represent bit masks that are not on byte boundaries).
> >
> > The C bit notation should never be, and should never /have/ been, used to
> > specify in-memory layout.
> >
> > The layout of bitfields is almost totally non-portable. IIRC, the only
defined
> > requirement is that they appear in memory in the same order as they do in
the
> > source, how much padding -- if any -- is between them is totally
implementation
> > specific. There might be problems with signedness too, but my memory of
that
> > aspect of the standard has faded completely 
> >
> > (All the above, of course, is true for C structs in general, but bitfields
are
> > even worse than usual because there seems to be a nearly irresistible
> > temptation for C programmers to abuse them.)
> >
> > In essence you will have to do exactly what you would do if you were
> > interfacing with those legacy systems using C. Find out how the compiler
for
> > the legacy code lays out the data in memory, read the data in as some
primitive
> > type (byte or int seems natural), and define appropriate bitmasks that
overlay
> > the layout to extract the data you want.
> >
> > I would avoid JNI for this sort of thing, if I were you -- all you are doing
is
> > putting off the problem (which is really caused by whoever it was who
thought
> > you could use C structs and bitfields to define memory layout portably), and
> > the cost of crossing the JNI boundary is quite high (I put it at in the
order
> > of magnitude of 1 usec on the machines I use).
> >
> > -- chris
>
>
> Chris,
>
> Thanks for feedback. It is unfortunate that the C Structs do not just
> support primitive types. That's a constraint placed upon us by the
> legacy device message interface. My initial thought was to leverage
> the C based JNI layer to overlay the input bag of bytes using the C
> Struct, extract the fields (leveraging the underlying C code to
> minipulate the bits), and then retain in the target Java Object via
> the JNI calls. Is the run-time cost of this approach less/more
> efficient then doing all the bit minipulation in Java via home-grown
> conversion utilities ???
I had this problem for implementing a TCP/IP layer that
could speak both Java and C. I used the java.nio packages
for the SocketChannel and ByteBuffer things. I defined
each message packet as a collection of fields with the
various primitive types. The "definition" was an XML
specification file that is processed by a Java language
program generator. The program generator spits out the
Java and C source files that can manage the message
packets.
The Java side has a class for each message packet type.
The class has getter/setter methods for each field that
can read/write the value from/to the ByteBuffer at the
appropriate offset.
The C side has a set of functions (similar to a Java
class) for each message packet type. The functions support
reading/writing the field values to a byte array buffer.
The functions are named similarly to the Java getter/setter
methods and referenced through function pointers in a
generated struct to avoid name clashes between different
message packet types. For example, there are several
types that each have a "threadId" field. Each "class" has
a "getThreadId" and a "setThreadId" function, which are
actually function pointer fields in a "class" struct.
The whole thing is managed by a Java GUI that displays/edits
the contents of the XML specification file using JTables.
Adding/changing field names and types is very simple with
the GUI. A button click generates the Java and C source
code, which I then compile in the usual way.
The "client" code that uses the generated code simply calls
the getter/setter methods to read/write the various fields.
"Endianness" is also handled transparently by specifying
whether the C code is expecting Big versus Little Endian.
(The Java side is always Big Endian.) The ByteBuffer has an
Endianness flag.
btw: This mechanism doesn't support C bit fields. Instead I
use the usual bitwise AND/OR masking to process the individual
bits of a byte field. Using bit masks, instead of bit
fields, insulates my code from the weird ordering and
boundaries of bits within a bit field.
--
----------------------------
Jeffrey D. Smith
Farsight Systems Corporation
24 BURLINGTON DRIVE
LONGMONT, CO 80501-6906
http://www.farsight-systems.com
z/Debug debugs your Systems/C programs running on IBM z/OS for FREE!