From: "REH" <me@you.com>
Subject: Re: How to pass two dimensional arrays to C
Date: Sat, 29 Jul 2006 04:19:14 GMT
Date: 2006-07-29T04:19:14+00:00 [thread overview]
Message-ID: <6lByg.12373$1Z5.8869@twister.nyroc.rr.com> (raw)
In-Reply-To: 1154119563.642347.13670@b28g2000cwb.googlegroups.com
"Jerry" <lanceboyle@qwest.net> wrote in message
news:1154119563.642347.13670@b28g2000cwb.googlegroups.com...
> Thanks for everyone's comments. I have thin bindings to PLplot nearly
> complete except for this nagging 2D array thing. (I also have a partial
> thick binding plus some easy-to-use one-line plotters as well.)
>
With respect to everyone, I believe you being led a little astray. C does
have multidimensional arrays. The problems they are at a lower level than
Ada's array, and less convenient. For you to call C, and send it an array
from Ada, you have to deal with a few issues:
1. When used as a function parameter, an array will "decay" to a pointer to
the first element of the array. This can be inconvenient because
information about the size and dimensions of the array are lost. Arrays are
not "first class" citizens. You can make them so by wrapping them in
structs, but this only works if you know the dimensions at compile type.
So, that is limited use.
2. What "type" of array? There can be a couple of different types in C,
because of their close relationship to pointers. One type is the simple
contiguous array: a[x][y]; Though, one might argue that this is not a 2d
array, but an array of arrays. That's just semantics, and doesn't matter.
The elements will be layed out the same assuming the elements are the same
and row major ordering is used (so, for Fortran, you would reverse the
dimensions, since it uses column major ordering). The second type is called
a jagged array, which is an array of pointers. You can simulate this form
in Ada using an array of access types to the second dimension. And for both
languages, an access to and element of the jagged array uses that same
syntax as a 2d array.
3. Are the dimensions constant? As long as all but the first dimension is
constant, it is simply a matter of giving C a pointer to an object whose
type is your array type minus the first dimension (again, assume the memory
is layed out the same). So, if in Ada we have (ignoring necessay pragmas
and/or rep. specs.):
type A is array (1 .. 10, 1 .. 10) of Interface.C.int;
type pA is access all A;
we can map this in C several ways. One easy to understand way is:
typedef A[10][10];
void foo(A* P);
this would map to an Ada procedure thus:
procedure foo(P : in pA);
This has the advantage of C "knowing" the dimensions, but is inconvenient
because because P has to be dereferenced before dimensions may be applied:
(*P)[1][2]; *** remember that the dimensions now in C, so the ranges for
both are 0 to 9.
Another way would be:
typedef A[10];
void foo(A* P);
To map this, we must either use System.Address and lose type safety or
change A to be an array of array and use an access type to the second
dimension array (messy).
procedure foo(P : in System.Address);
call foo with A[1,1]'Address.
This makes the C code nicer, in that we can now just say P[1][2];
Both methods assume the dimensions are constant. If only the first
dimension is variable, use the second method above, and send C that
dimension via another parameter. If both dimensions are variable, this is
more problematic because C cannot define array types with variable
dimensions. All this means is that you have to calculate the indexing
yourself. This is a pain and error-prone, but at least it is not
insurmountable. For example (assume the element type is still int):
foo(void* P, int x, int y);
Here we calculate P[1][2] thus:
const sx = sizeof(int) * y;
const sy = sizeof(int);
int* I = P;
int v = P + sx * 1 + sy * 2; *** again, remembering that the dimensions are
now zero-based.
Messy, but doable. You should create a function to do the indexing and
return the element. If using C99, make it inline.
Jagged arrays are even messier. These are just arrays of pointers. They
allow the creation of arrays where the second dimension is of varying
length. The problem is that C will not intrinsically know the lengths, and
thus you will probably have to give it an array of lengths as a second
parameter. But, most likely, if you are going from Ada to C, you aren't
dealing with these.
I probably made some mistakes above in my haste, but you should get the
gist.
REH
next prev parent reply other threads:[~2006-07-29 4:19 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 [this message]
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
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