From: Adrian Hoe on
Hi,

I have a C library function which takes a float * as a parameter. The
function is as below:

int pwmRead (int pwmCount, float * data);

where data is an array of float which size is determined by pwmCount.

In Ada, I have:

PWM_Count : Integer := No_Of_Components_Intended;
PWM_Data : array (1 .. PWM_Count) of Float;

My concern is how safe to pass an Ada array to a C function as a
pointer (call by reference)? I presume Ada will allocate contiguous
memory for array, but what if it does not? How can we establish a
deterministic allocation and to make sure float * is accessed
contiguously? Is there any "safe" way to do this?

Thanks.
--
Adrian Hoe
http://adrianhoe.com
From: Adrian Hoe on
On Jun 27, 9:39 am, Adrian Hoe <aby...(a)gmail.com> wrote:
> Hi,
>
> I have a C library function which takes a float * as a parameter. The
> function is as below:
>
> int pwmRead (int pwmCount, float * data);
>
> where data is an array of float which size is determined by pwmCount.
>
> In Ada, I have:
>
> PWM_Count : Integer := No_Of_Components_Intended;
> PWM_Data : array (1 .. PWM_Count) of Float;
>
> My concern is how safe to pass an Ada array to a C function as a
> pointer (call by reference)? I presume Ada will allocate contiguous
> memory for array, but what if it does not? How can we establish a
> deterministic allocation and to make sure float * is accessed
> contiguously? Is there any "safe" way to do this?
>
> Thanks.
> --
> Adrian Hoehttp://adrianhoe.com


Sorry, PWM_Count should be declared as constant:

PWM_Count : constant := No_Of_Components_Intended;
From: Adam Beneschan on
On Jun 26, 6:39 pm, Adrian Hoe <aby...(a)gmail.com> wrote:
> Hi,
>
> I have a C library function which takes a float * as a parameter. The
> function is as below:
>
> int pwmRead (int pwmCount, float * data);
>
> where data is an array of float which size is determined by pwmCount.
>
> In Ada, I have:
>
> PWM_Count : Integer := No_Of_Components_Intended;
> PWM_Data : array (1 .. PWM_Count) of Float;
>
> My concern is how safe to pass an Ada array to a C function as a
> pointer (call by reference)? I presume Ada will allocate contiguous
> memory for array, but what if it does not?

I've never heard of an Ada compiler that doesn't, absent some explicit
instruction (like a pragma) to do something unusual. Even so, if
you're thinking of using an Ada compiler written on the planet
Zorxkrug where they might do some odd array allocation, you should
still be OK if you use the Convention pragma. First of all, you
cannot declare PWM_Data with an anonymous array type, because then you
couldn't pass it as a parameter to *any* routine (what would the
parameter type be??). So something like this should work:

type Float_Array is array (Natural range <>) of Float;
pragma Convention (C, Float_Array);
PWM_Data : Float_Array (1 .. PWM_Count);

and now even the Zorxkrugian Ada compiler should allocate the array in
a way that will be compatible with the C code. (In the Ada
declaration of pwmRead, the second parameter would have type
Float_Array.)

No guarantees, but a compiler that follows the Implementation Advice
should handle this correctly.

Oh, and you probably want to use Interfaces.C.C_Float instead of the
Ada type "Float", to ensure that you're using the same kind of float
that the C routine expects.

Hope this helps,

-- Adam
From: Jeffrey R. Carter on
Adrian Hoe wrote:
>
> int pwmRead (int pwmCount, float * data);
>
> where data is an array of float which size is determined by pwmCount.
>
> In Ada, I have:
>
> PWM_Count : Integer := No_Of_Components_Intended;
> PWM_Data : array (1 .. PWM_Count) of Float;
>
> My concern is how safe to pass an Ada array to a C function as a
> pointer (call by reference)? I presume Ada will allocate contiguous
> memory for array, but what if it does not? How can we establish a
> deterministic allocation and to make sure float * is accessed
> contiguously? Is there any "safe" way to do this?

type C_Data is array (Positive range <>) of Interfaces.C.C_Float;
pragma Convention (C, C_Data);

function PWM_Read (Count : in Interfaces.C.Int; Data : in C_Data)
return Interfaces.C.Int;
pragma Import (C, PWM_Read, "pwmRead");

PWM_Count : constant := ...;

PWM_Data : C_Data (1 .. PWM_Count);
Result : Interfaces.C.Int;

Result := PWM_Read (PWM_Count, PWM_Data);

--
Jeff Carter
"Your mother was a hamster and your father smelt of elderberries."
Monty Python & the Holy Grail
06
From: Adrian Hoe on
On Jun 27, 12:10 pm, "Jeffrey R. Carter"
<spam.jrcarter....(a)spam.acm.org> wrote:
> Adrian Hoe wrote:
>
> > int pwmRead (int pwmCount, float * data);
>
> > where data is an array of float which size is determined by pwmCount.
>
> > In Ada, I have:
>
> > PWM_Count : Integer := No_Of_Components_Intended;
> > PWM_Data : array (1 .. PWM_Count) of Float;
>
> > My concern is how safe to pass an Ada array to a C function as a
> > pointer (call by reference)? I presume Ada will allocate contiguous
> > memory for array, but what if it does not? How can we establish a
> > deterministic allocation and to make sure float * is accessed
> > contiguously? Is there any "safe" way to do this?
>
> type C_Data is array (Positive range <>) of Interfaces.C.C_Float;
> pragma Convention (C, C_Data);


Can I use Float instead of Interfaces.C.C_Float?

One question has been raised to me:

Why use Interfaces.C.Int, Interfaces.C.C_Float since they are all new
declaration of Ada types.

I know it is for readability and maintainability but the question is
logical as the declaration in Interfaces.C is just merely creating a
new Ada type with a new name, unless there is pragma Convention
statement after every such declaration in Interfaces.C.

So, that leads to another question:

Wouldn't it be better to write as such?

type C_Data is array (Positive range <>) of Float;
pragma Convention (C, C_Data);



> function PWM_Read (Count : in Interfaces.C.Int; Data : in C_Data)
> return Interfaces.C.Int;
> pragma Import (C, PWM_Read, "pwmRead");
>
> PWM_Count : constant := ...;
>
> PWM_Data : C_Data (1 .. PWM_Count);
> Result : Interfaces.C.Int;
>
> Result := PWM_Read (PWM_Count, PWM_Data);

Is PWM_Data passed as pointer to pwmRead?

Thanks again.
--
Adrian Hoe
http://adrianhoe.com