|
From: Adrian Hoe on 26 Jun 2008 21:39 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 26 Jun 2008 21:42 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 26 Jun 2008 22:55 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 27 Jun 2008 00:10 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 27 Jun 2008 04:22
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 |