Reputation: 3
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
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