From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.5-pre1 (2020-06-20) on ip-172-31-74-118.ec2.internal X-Spam-Level: X-Spam-Status: No, score=-1.9 required=3.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.5-pre1 Date: 18 Aug 93 02:11:59 GMT From: cis.ohio-state.edu!magnus.acs.ohio-state.edu!usenet.ins.cwru.edu!agate!do g.ee.lbl.gov!network.ucsd.edu!news.cerf.net!shrike.irvine.com!adam@ucbvax.Berke ley.EDU (Adam Beneschan) Subject: Re: Data Overlays Message-ID: List-Id: In article <1993Aug18.003940.2208@leeweyr.sccsi.com> bill@leeweyr.sccsi.com (Bill Lee) writes: > O.k., Here's my problem: > > I have a system which receives "messages" from a number of other > systems. The messages come via POSIX queues. On any one queue, I > can receive a number of different messages, mostly with record > structures defined by the C code where the message originated. > > I do not know a priori what the next message will be. I have to > "receive" the message into a Byte_Array. Once I have the message, > I can access a standard header and extract a message identifier, > which then tells me what kind of message I've just received. > Once I have a message in a Byte_Array, and once I know what kind > of message it is, I can then convert the message to an Ada record > which has the right structure for the message. > > I've considered both methods above. Certainly, Unchecked_Conversion > is one alternative. But I have used another method which seems to > work, seems to be portable, and, moreover, SEEMS to be in line with > what the language designers intended. To wit: > > Given an Ada type, Messages: > > generic > type Byte_Arrays is private; > function Extract_Message ( A_Message : in Byte_Arrays ) return Messages; > > where the body looks like > > function Extract_Message ( A_Message : in Byte_Arrays ) return Messages is > Temp_Message : Messages; > for Temp_Message use at A_Message'address; > begin > return Temp_Message; > end Extract_Message; > > In many cases, I have actually created a more "Ada-like" message > type, and I do far more than just return the C structure. > > I like the "feel" of this method. It uses the representation > specification which allows a structure to be placed "at" an address. > If this usage is not what the language designers had in mind, then > what was the purpose of the rep spec? I believe the purpose of the "for...use at" clause is to allow you to declare data whose address is fixed by, say, the processor architecture or the operating system. > Is there any inherent danger or "wrongness" in this technique? And > yes, I have read the "for the purpose of overlaying....erroneous" > section in the LRM. Is this overlaying? Is it erroneous? Yep, it's overlaying, since you have two Ada objects (A_Message and Temp_Message) that you've declared to be at the same location. > Incidently, I use this same technique in bindings where I have to > deal with structures created in C. The C code malloc's the memory > and places structs in it, and then just passes back the C pointer. > I make the assumption (possibly in error in some cases) that a C > pointer and a System.Address are coincident. Then I can calculate > the address in the malloc'ed memory where a specific C structure > exists, and I can assign an Ada record "at" that address in order > to extract the information from it. I'm assuming here that you're using PRAGMA IMPORT_FUNCTION or something to get at your C code. If that's the case, why not just make the Ada function declaration return an ACCESS type to the desired Ada structure? (Unless, of course, you don't know beforehand which Ada type the C function result will point to.) You shouldn't even have to worry about possible differences in representation between a C pointer and an Ada access object; DEC Ada is good at taking care of those things for you. -- Adam