comp.lang.ada
 help / color / mirror / Atom feed
From: "Dr. Adrian Wrigley" <amtw@linuxchip.demon.co.uk.uk.uk>
Subject: C bindings, Interfaces.C.Pointers etc.
Date: Tue, 11 May 2004 14:14:30 +0100
Date: 2004-05-11T14:14:30+01:00	[thread overview]
Message-ID: <pan.2004.05.11.13.14.28.345191@linuxchip.demon.co.uk.uk.uk> (raw)

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?)

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?

3)  How do I access the n'th element of the Array, given the
   C pointer.

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.

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).

Any ideas?
--
Adrian Wrigley, Cambridge, England


procedure Problem is

-- C code is:
--
-- struct node
-- {
--      int index;
--      double value;
-- };

-- struct problem
-- {
--      node **x;
-- };

-- x is a pointer to an array of pointers to arrays of nodes (both variable size)

   type Node_T is record
      Index : Interfaces.C.Int;
      Value : Interfaces.C.Double;
   end record;
   pragma Convention (C, Node_T);

   type NodeArray_T is array (Interfaces.C.Size_T range <>) of Node_T;
   pragma Convention (C, NodeArray_T);
   type NodeArray_A is access all NodeArray_T;
   pragma Convention (C, NodeArray_A);

   type NodeArrayArray_T is array (Interfaces.C.Size_T range <>) of NodeArray_A;
   pragma Convention (C, NodeArrayArray_T);
   type NodeArrayArray_A is access all NodeArrayArray_T;
   pragma Convention (C, NodeArrayArray_A);

   type Problem_T is record
      X : NodeArrayArray_A;
   end record;
   pragma Convention (C, Problem_T);

   MyProblem : Problem_T;
   MyNode : Node_T;

begin

   MyProblem := (X => new NodeArrayArray_T (1 .. 100));

   for I in MyProblem.X'range loop
      MyProblem.X (I) := new NodeArray_T (1 .. I);
   end loop;

   MyNode := MyProblem.X (10)(5);

end Problem;




             reply	other threads:[~2004-05-11 13:14 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-05-11 13:14 Dr. Adrian Wrigley [this message]
2004-05-11 18:17 ` C bindings, Interfaces.C.Pointers etc 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
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