Right way to pass arrays to interface with C

I often find myself needing to do arrays of things to interface with C.

What’s the Ada way of doing this?

It seems like passing an array with An_Array'Address seems to work, but I’m not sure how the array’s bounds are stored and affect the layout of that array. This is particular importance since I’m looking at trying to store multiple arrays of potentially difference sizes allocated in memory sequentially.

struct Vec3 {
    float x, y, z;
};

uint32_t size = 10;
Vec3 points = new Vec3[size];
passArrayToFunc(&points[0], size);

It can be done like this:

   type Vec3 is record
      X, Y, Z : Interfaces.C.c_float;
   end record with Convention => C;

   type Vec3_Array is array (Positive range <>) of aliased Vec3;

   procedure Pass_Array_To_Func
     (Pointer : not null access Vec3;
      Size    : Interfaces.C.int) with Import, Convention => C;
   
   Points : Vec3_Array (1 .. 10);
   
begin
   Pass_Array_To_Func (Points (Points'First)'Access, Points'Length);

An idea is to pass address of the first element of the array and length of the array.

I think the RM explicitly says Points'Access is the same as Points (Points'First)'Access.

That is true for 'Address. Ada RM 13.3(14):

For an array X, X’Address should point at the first component of the array, and not at the array bounds.

But for 'Access, those two are of different access types.

How I can expect the array overall to be laid out in memory, such as if I wanted to allocated two arrays adjacent in memory? Is that even defined?

First                  Second
[ 1 ]  [ 2 ]  [ 3 ]   [ 1 ] [ 2 ] [ 3 ]

Indeed :man_facepalming: I thought Vadim was talking about addresses here…

Perhaps you could say

for Second’Address use First’Address
  + First_Type’Max_Size_In_Storage_Elements;

(or the new ’Object_Size, divided by the storage element size).
But you’d need to be wary of alignment.

Alternatively, declare a type with the two arrays and give a rep clause.