comp.lang.ada
 help / color / mirror / Atom feed
From: tmoran@bix.com
Subject: Re: New to ada95: porting
Date: 2000/03/01
Date: 2000-03-01T00:00:00+00:00	[thread overview]
Message-ID: <Pv4v4.120$im1.7120@news.pacbell.net> (raw)
In-Reply-To: 38BC5237.91FD3B95@mindspring.com

If it doesn't cost too much in data copying, could you make a few
wrapper functions to take the C results, copy the data into an
Ada object, free the C allocated memory, and return the Ada object,
along the lines:

  type A is array(index_type <>) of some_element;

  function Wrapped_C_Fun(Params:whatever) return A is
    use System.Storage_Elements;
    Dope_Offset : constant Storage_Offset := 16; -- 128/8 bit Storage_Elements
    type Dummy_A is A(0 .. index_type'last);  -- fixed, though large, size
    package Addr_Acc_Dummy_A is new
      System.Address_To_Access_Conversions(Dummy_A);
    type C_Returned_Ptr_Type is access Dummy_A;
    function C_Fun(Params:whatever) return C_Returned_Ptr_Type;
    pragma Import(C, C_Fun, "CFun");
    Data_Ptr : C_Returned_Ptr_Type := C_Fun(Params);  -- call the C function
    Data_Address : constant System.Address
      := Addr_Acc_Dummy_A.To_Address(Data_Ptr);
    Dope_Address : constant System.Address := Dope_Address - Dope_Offset;
    type Dope is record
      Size, Lower_Bound, Upper_Bound, Byte_Count : Integer;
      Data : Dummy_A;
    end record;
    for Dope use
      Size        at 0 range 0 .. 31;
      Lower_Bound at 4 range 0 .. 31;
      Upper_Bound at 8 range 0 .. 31;
      Byte_Count  at 12 range 0 .. 31;
      Data        at 16 range 0 .. (index_type'last+1)*some_element'size-1;
    end record;
    type Dope_Ptr_Type is access Dope;
    package Addr_Acc_Dope is new
      System.Address_To_Access_Conversions(Dope_Ptr_Type);
    Dope_Ptr : constant Dope_Ptr_Type
      := Addr_Acc_Dope.To_Access(Dope_Address);
    Result : A(Dope_Ptr.Lower_Bound .. Dope_Ptr.Upper_Bound);
  begin
    if Dope_Ptr.Size /= some_element'size then raise an_exception;end if;
    if Dope_Ptr.Byte_Count /= Result'size/8 then raise an_exception;end if;
    -- first copy the returned array from the C structure to an A.
    Result := Data_Ptr.all(0 .. Result'length-1);
    -- free the C memory
    C_Free(Dope_Ptr);
    -- return result of type A.
    return Result;
  end Wrapped_C_Fun;

Note: this code untested and written after midnight.




      parent reply	other threads:[~2000-03-01  0:00 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2000-02-28  0:00 New to ada95: porting Al Johnston
2000-02-29  0:00 ` James S. Rogers
2000-02-29  0:00   ` Al Johnston
2000-02-29  0:00     ` tmoran
2000-02-29  0:00       ` Al Johnston
2000-02-29  0:00         ` james hopper
2000-03-01  0:00           ` Al Johnston
2000-03-01  0:00         ` tmoran [this message]
replies disabled

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