A Mara
A Mara

Reputation: 3

Ada arrays of access type

Ada Coders,

I am trying to pass an array of pointers to a C function from Ada. I am new to Ada.

Here's the code:

with Interfaces.C; use Interfaces.C;
with asm_generic_int_ll64_h; use asm_generic_int_ll64_h;

block : array(Integer range 1 .. 6) of access uu_u8;
one : aliased uu_u8 := uu_u8(1);
two : aliased uu_u8 := uu_u8(2);
three : aliased uu_u8 := uu_u8(3);
four : aliased uu_u8 := uu_u8(4);
five : aliased uu_u8 := uu_u8(5);
six : aliased uu_u8 := uu_u8(6);

ans : uu_u8;

begin

block(1) := one'Access;
block(2) := two'Access;
block(3) := three'Access;
block(4) := four'Access;
block(5) := five'Access;
block(6) := six'Access;

call_c_func(block(1));

ans := block(1).all;

The last line causes an error:

raised STORAGE_ERROR : stack overflow (or erroneous memory access)

Thank you in advance!

Upvotes: 0

Views: 777

Answers (1)

flyx
flyx

Reputation: 39638

From your comments, it is clear that you use a wrong array type.

Your array on the Ada side is an array of pointers to uu_8. However, on the C side, __u8* is expected, i.e. a pointer to a __u8 value. The types are not compatible.

In C, arrays are typically passed as pointer to the first element. This is the case here. So what you actually need on the Ada side is an array with uu_8 values in it:

type My_Array is array (Integer range <>) of uu_8;
pragma Convention (C, My_Array);

Block : My_Array := (1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5, 6 => 6);

function read_i2c_block_data
  (file : int;
   command : asm_generic_int_ll64_h.uu_u8;
   length : asm_generic_int_ll64_h.uu_u8;
   values : in out My_Array) return asm_generic_int_ll64_h.uu_s32;
pragma Import (C, read_i2c_block_data, "read_i2c_block_data");

The compiler will map your Ada array to a pointer to the first element when having convention C and used in a function imported with C calling convention. in out tells Ada that the C function may modify the array.

Upvotes: 2

Related Questions