comp.lang.ada
 help / color / mirror / Atom feed
From: "David C. Hoos, Sr." <david.c.hoos.sr@ada95.com>
Subject: Re: simple question - how to emulate void * ?
Date: 1998/10/23
Date: 1998-10-23T00:00:00+00:00	[thread overview]
Message-ID: <TVmKcjn$9GA.189@samson.airnet.net> (raw)
In-Reply-To: dale-2310981318260001@dale.ppp.cs.rmit.edu.au

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 of 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<len; ++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 -------------------------










  parent reply	other threads:[~1998-10-23  0:00 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1998-10-23  0:00 simple question - how to emulate void * ? Craig Allen
1998-10-23  0:00 ` Tom Moran
1998-10-23  0:00 ` Dale Stanbrough
1998-10-22  0:00   ` Hans Marqvardsen
1998-10-22  0:00   ` Hans Marqvardsen
1998-10-23  0:00     ` John McCabe
1998-10-23  0:00       ` dennison
1998-10-23  0:00       ` Ed Falis
1998-10-23  0:00         ` dennison
1998-10-24  0:00           ` Joe Wisniewski
1998-10-25  0:00           ` dewar
1998-10-24  0:00         ` Dale Stanbrough
1998-10-24  0:00           ` Robert A Duff
1998-10-24  0:00           ` Tucker Taft
1998-10-23  0:00   ` David C. Hoos, Sr. [this message]
1998-10-23  0:00   ` David C. Hoos, Sr.
1998-10-23  0:00 ` Jeff Carter
1998-10-24  0:00   ` Dale Stanbrough
1998-10-25  0:00     ` dewar
1998-11-05  0:00 ` Craig Allen
1998-11-06  0:00   ` Dale Stanbrough
1998-11-06  0:00     ` Matthew Heaney
1998-11-06  0:00       ` dewarr
1998-11-06  0:00   ` Tom Moran
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox