comp.lang.ada
 help / color / mirror / Atom feed
From: "REH" <me@you.com>
Subject: Re: How to pass two dimensional arrays to C
Date: Sat, 29 Jul 2006 05:47:52 GMT
Date: 2006-07-29T05:47:52+00:00	[thread overview]
Message-ID: <cECyg.12377$1Z5.4438@twister.nyroc.rr.com> (raw)
In-Reply-To: 1154084819.088112.325730@p79g2000cwp.googlegroups.com


"Jerry" <lanceboyle@qwest.net> wrote in message 
news:1154084819.088112.325730@p79g2000cwp.googlegroups.com...
> In my project to write a binding for a popular plotter written in C,
> I've hit a brick wall and the problem might be associated with passing
> two-dimensionaal arrays to C. I'm using GNAT on OS X and Xcode. I can
> pass one-dimensional arrays OK. Here are the pertinent parts from an
> example where the problem happens:
>
>
>      The C
>
>
> typedef double PLFLT;
> typedef int PLINT;
>
> void c_plmesh(PLFLT *x, PLFLT *y, PLFLT **z, PLINT nx, PLINT ny, PLINT
> opt);
>
>
>
>      The Ada
>
>
> type Long_Float_Array_1D is array (Integer range <>) of Long_Float;
> type Long_Float_Array_2D is array (Integer range <>, integer range <>)
> of Long_Float;
>
> subtype PLINT  is Integer;
>
> subtype PL_Float_Array    is Long_Float_Array_1D;
> subtype PL_Float_Array_2D is Long_Float_Array_2D;
>
> procedure plmesh(
>    x   : PL_Float_Array;
>    y   : PL_Float_Array;
>    z   : PL_Float_Array_2D;
>    nx  : PLINT;
>    ny  : PLINT;
>    opt : PLINT);
> pragma Import(C, plmesh, "c_plmesh");
>
>
>
>      And the Ugly
>
>
> AdaPLplotProject has exited due to signal 11 (SIGSEGV).
>
> This appears during the call to plmesh. Any ideas?
>
> Thanks,
> Jerry
>

That's because C is not expecting to see a 2d array, but an array of 
pointers (jagged array).  If C were looking for an actual 2d array of 
contiguous memory, you would see something like:

void foo(int A[][10]);

or even:

void foo(int (*A)[10]);

What you need to do is give it an array of access types to arrays. 
Something like:

type D2 is array (1 .. 10) of Interface.C.double;
pragma Convention(C, D2);

type PD2 is access all D2;
pragma Convention(C, PD2);

type D2Arrays is array (1 .. 3) of aliased D2;
pragma Convention(C, D2Arrays);

type D1 is array (1 .. 3) of PD2;
pragma Convention(C, D1);

T : D2Arrays;
Z : D1 := (1 => T(1)'Access, 2 => T(2)'Access, 3 => T(3)'Access) ;

Z should now be usable in your function for PLFLT **

Note, that PLFLT ** alone doesn't tell you what C really wants.  I had to go 
on the internet and search for your function to find out.  It could have 
also meant the function was expecting a pointer to a pointer (a pointer by 
reference, so a pointer can be "returned").  It could also have meant that 
the function was going to allocate and "return" a 1d array.  It could also 
have been an actual 2d array (with unknown dimensions).

REH





  parent reply	other threads:[~2006-07-29  5:47 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-07-28 11:06 How to pass two dimensional arrays to C Jerry
2006-07-28 12:27 ` Jeffrey Creem
2006-07-28 12:27 ` Dmitry A. Kazakov
2006-07-28 16:53 ` Adam Beneschan
2006-07-28 20:15 ` Jeffrey R. Carter
2006-07-28 20:46 ` Jerry
2006-07-28 21:14   ` Jeffrey Creem
2006-07-28 22:54   ` Björn Persson
2006-07-29  1:14     ` Jeffrey R. Carter
2006-07-29  7:11       ` Simon Wright
2006-07-29 22:12         ` Jeffrey R. Carter
2006-07-30 11:18           ` Simon Wright
2006-07-30 11:20           ` Simon Wright
2006-07-29  4:19   ` REH
2006-07-29  4:28     ` REH
2006-07-29  4:30       ` REH
2006-08-14  6:59     ` Dave Thompson
2006-07-29  5:47 ` REH [this message]
2006-08-02  8:20 ` Jerry
2006-08-02  9:03   ` Dmitry A. Kazakov
2006-08-02 10:22     ` Jerry
2006-08-02 18:25   ` Björn Persson
2006-08-05  1:03 ` Jerry
replies disabled

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