comp.lang.ada
 help / color / mirror / Atom feed
From: Martin Krischik <krischik@users.sourceforge.net>
Subject: Re: C bindings, Interfaces.C.Pointers etc.
Date: Wed, 12 May 2004 08:30:04 +0200
Date: 2004-05-12T08:30:04+02:00	[thread overview]
Message-ID: <4934218.sMSg6xXRUe@linux1.krischik.com> (raw)
In-Reply-To: pan.2004.05.11.13.14.28.345191@linuxchip.demon.co.uk.uk.uk

Dr. Adrian Wrigley wrote:

> Hi folks!
> 
> I have a problem creating a binding to a C library.
> 
> The library makes extensive use of arrays of arrays of structs.
> Both levels of arrays are of variable length.
> 
>  struct node { int index; double value; };
>  struct problem { node **x; };
> 
> When I attempt to define Ada types for this type of thing,
> I find I can't use access types to the arrays with the
> necessary C convention.
> "warning: this access type does not correspond to C pointer"
> is the compiler error.
> 
> I have tried using Interfaces.C.Pointers, but I have run
> into (soluble?) problems.
> 
> 1)  How to I allocate an array (in Ada) and assign it to a
>    C pointer? (in a single expression?)

Ada_Array : <some array>

C_Pointer  :  constant C_Pointers.Pointer := Ada_Array (0)'Unchecked_Access;

Depending on how Ada_Array is defined it might work without Unchecked_.
 
> 2)  How do I free the allocaed array from the C pointer?
>    Do I need to keep track of the return values from "new"
>    separately from the pointers?

Since the Pointer are for use with C you might consider:

   function malloc (Size : size_t) return System.Address;
   pragma Import (C, malloc, "malloc");
   procedure free (Ptr : System.Address);
   pragma Import (C, free, "free");

You can either combine it with package System.Address_To_Access_Conversions
or a special Storrage_Pool.
 
> 3)  How do I access the n'th element of the Array, given the
>    C pointer.

Depending on actual use You can either convert the C array to an Ada array
or use:

Access_Pointer := Base_Pointer + n;

... Base_Pointer.all ...

> 4)  Is there some convenient shortcut to avoid using I.C.P?
>    perhaps by declaring an Ada constrained array much larger than
>    intended, and using a subset.
>    Using I.C.P seems massively verbose (10x) for this application.

From you example down I suggest "aliased" Elements

type NodeArray_T is array (Interfaces.C.Size_T range <>) of  aliased Node_T;
type NodeArrayArray_T is array (Interfaces.C.Size_T range <>) of aliased 
NodeArray_A;

then you can use I.C.P.Value and I.C.P.Copy_Array as alternative to pure
Pointer use. Giving you more flexibility.
 
> As I understand it, if the array is unconstrained, an access type
> to the array contains the dope information, and can't be used
> as a C pointer.
> 
> I have given an example of my problem code below (without I.C.P).

Well, it does look Ok to me. Apart from the missing "aliased". All elements
in an C array need an address while in Ada they don't. (Look for pragma
Pack and the attributes 'Size and 'Component_Size for details).

With Regards

Martin
-- 
mailto://krischik@users.sourceforge.net
http://www.ada.krischik.com




  parent reply	other threads:[~2004-05-12  6:30 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-05-11 13:14 C bindings, Interfaces.C.Pointers etc Dr. Adrian Wrigley
2004-05-11 18:17 ` tmoran
2004-05-11 18:48 ` Jeffrey Carter
2004-05-12  4:50   ` Simon Wright
2004-05-13 15:26   ` Dr. Adrian Wrigley
2004-05-12  6:30 ` Martin Krischik [this message]
2004-05-13 15:56   ` Dr. Adrian Wrigley
2004-05-13 17:37     ` Martin Krischik
2004-05-13 22:42     ` Jeffrey Carter
replies disabled

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