From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,af247e41be5f18ab X-Google-Attributes: gid103376,public From: "David C. Hoos, Sr." Subject: Re: simple question - how to emulate void * ? Date: 1998/10/23 Message-ID: #1/1 X-Deja-AN: 404260087 References: <9v6hGdgMLuwN-pn2-Oc41W71Dq3U9@dt182n2f.tampabay.rr.com> Newsgroups: comp.lang.ada X-MimeOLE: Produced By Microsoft MimeOLE V4.72.3110.3 Date: 1998-10-23T00:00:00+00:00 List-Id: The trouble with Dale's solution is that it doesn't meet Craig's requirement that the data be able to be of any type. Further, Dale's liberal use uf use clauses obscures the fact that To_Pointer is really Char_Addr.To_Pointer, thus rendering the procedure Print_Bytes suitable only for arrays of characters -- i.e. strings. The solution at the end of this post does meet Craig's requirement. Because my Print_Bytes procedure is type-independent, I print each byte's hexadecimal value. David C. Hoos, Sr. Dale Stanbrough wrote in message ... >Craig Allen wrote: > > Well, yes, I'm new to ada, and coming from C. > > Now, I have some simple functionality that I'd like to see, and can't > figure out how to do it in Ada. > > in C, it goes like this: > > /* libfile.c */ > > void print_bytes(void *buf, int len) > { > int i; > char *c = buf; > for (i=0; i putchar(c[i]); > } > > return; > } > > /* app.c */ > ... > struct any_struct data; > print_bytes(&data, sizeof (struct data)); > ... > > The lib can access byte for byte the data passed in regardless of the > app's struct type. Now, Ada being such a strongly typed language, I > have tried different things but just can't seem to figure out how to > get this lib routine to work on my buffer, regardless of its type. > I've come close with some generic functions, but can't seem to get the > syntax acceptable for the compiler. > Can someone point me in the right direction?" > > >Try using the object's address... > >-------------------------------------------------------- >with System; use System; >with System.Storage_Elements; use System.Storage_Elements; >with System.Address_To_Access_Conversions; >with text_io; use text_IO; > > >procedure PB is > > package Char_Address is new System.Address_To_Access_Conversions (Character); > use Char_Address; > > > procedure Print_Bytes (Buffer : System.Address; Length : Integer) > is > Temp : System.Address; > begin > Temp := Buffer; > for i in 1..Length loop > Text_IO.Put (To_Pointer (Temp).all); > Temp := Temp + 1; > end loop; > end Print_Bytes; > > > > X : String := "Hello There"; >begin > > Print_Bytes (X'Address, X'Length); > >end; >-------------------------------------------------------- >(compiled and works using Gnat3.10, Sparc Solaris). > >Also the function "To_Pointer" is an intrinsic function, so it won't >incur any overhead (that i can see) for being called. All the package >Address_To_Access_Conversion does is explicity enforces what C does >implicity, and at the same cost (someone please correct me if i am >wrong)). > >Note that X'Length will give you the number of _Components_ in an >array, not the length (in bytes) of the array. > >You could also use streams, which (IMHO) is a much more versatile >tool. > >Dale --- begin file print_bytes.adb ------------------------- with Ada.Text_Io; with System.Storage_Elements; procedure Print_Bytes (At_The_Address : System.Address; Storage_Element_Count : Natural) is Elements_Per_Line : constant System.Storage_Elements.Storage_Count := 8; use type System.Storage_Elements.Storage_Offset; package Storage_Element_Io is new Ada.Text_Io.Modular_Io (System.Storage_Elements.Storage_Element); The_Data : System.Storage_Elements.Storage_Array (1 .. System.Storage_Elements.Storage_Count (Storage_Element_Count)); for The_Data'Address use At_The_Address; begin for E in The_Data'range loop if (E mod Elements_Per_Line) = 1 then Ada.Text_Io.New_Line; end if; Storage_Element_Io.Put (Item => The_Data (E), Width => 8, Base => 16); end loop; end Print_Bytes; --- end file print_bytes.adb ------------------------- --- begin file app.adb ------------------------- with print_bytes; with System.Storage_Elements; procedure App is subtype Storage_Element is System.Storage_Elements.Storage_Element; The_Data : constant array (Positive range <>) of Long_Float := (1.0, 2.0, 3.0, 4.0); begin Print_Bytes (At_The_Address => The_Data (The_Data'First)'Address, Storage_Element_Count => The_Data'Size / Storage_Element'Size); end App; --- end file app.adb -------------------------