* How to use Annex G.3 Vectors and Matrices in bindings to C arrays @ 2006-11-12 3:45 Jerry 2006-11-12 8:45 ` Yves Bailly 2006-11-12 19:39 ` Jeffrey R. Carter 0 siblings, 2 replies; 13+ messages in thread From: Jerry @ 2006-11-12 3:45 UTC (permalink / raw) A while back, I wrote a binding for a C program (PLplot) in which I have a declaration thus: type Long_Float_Array_1D is array (Integer range <>) of aliased Long_Float; and similarly for a 2D array. As I understand it (I'm a little unclear about this even though I did most of the work myself, help from this list notwithstanding), the aliasing of the array components was required in order to cause the pass-by-reference to the C code to work correctly. Now, I am working with the Annex G.3.1 and G.3.2 features which are new to Ada 2005, "Vector and Matrix Manipulation." I have those features working correctly on their own; however, it only makes sense to rationalize all 1D and 2D numerical arrays against the Annex G.3 features. Thus, I am looking into getting my PLplot binding to work with arrays which are (sub)typed from the Annex G.3 declarations. For example, here is the declaration from the spec of Ada.Numerics.Generic_Real_Arrays which is GNAT file a-ngrear.ads: type Real_Vector is array (Integer range <>) of Real'Base; (The Long_Float version, for example, is an instantiation of this generic and is named Ada.Numerics.Long_Real_Arrays.) So--how do I get objects and subtypes based on the type Real_Vector to have aliased components or, how do I get a type that is type-compatible with Real_Vector but which has aliased components? I wonder if I am incorrect in believing that the binding to C-arrays need aliased components. Like I said, the reason for that is a little fuzzy to me right now. But I do know that if I remove the aliased component requirement from Long_Float_Array_1D the binding will not compile. I also wonder if it is generally possible to rationalize other bindings which involve connecting to C arrays by using (sub)types of the Annex G.3 vector and matrix types. If not, that would seem to make the Annex G.3 features useless whenever C array bindings are needed. I next want to look into binding to the GNU Scientific Library (GS) and hope to be able to derive all the 1D and 2D arrays from those specified in Annex G.3. Thanks as always, Jerry ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to use Annex G.3 Vectors and Matrices in bindings to C arrays 2006-11-12 3:45 How to use Annex G.3 Vectors and Matrices in bindings to C arrays Jerry @ 2006-11-12 8:45 ` Yves Bailly 2006-11-13 10:48 ` Jerry 2006-11-12 19:39 ` Jeffrey R. Carter 1 sibling, 1 reply; 13+ messages in thread From: Yves Bailly @ 2006-11-12 8:45 UTC (permalink / raw) Jerry wrote: > with arrays which are (sub)typed from the Annex G.3 declarations. For > example, here is the declaration from the spec of > Ada.Numerics.Generic_Real_Arrays which is GNAT file a-ngrear.ads: Sorry for this off-topic quesiton, but which GNAT version are you using ? I just can't find this file in GNAT-GPL... > type Real_Vector is array (Integer range <>) of Real'Base; > (The Long_Float version, for example, is an instantiation of this > generic and is named Ada.Numerics.Long_Real_Arrays.) > > So--how do I get objects and subtypes based on the type Real_Vector to > have aliased components or, how do I get a type that is type-compatible > with Real_Vector but which has aliased components? > > I wonder if I am incorrect in believing that the binding to C-arrays > need aliased components. Like I said, the reason for that is a little > fuzzy to me right now. But I do know that if I remove the aliased > component requirement from Long_Float_Array_1D the binding will not > compile. Have you tried: type A is array(1..10) of Float; pragma Convention(C, A); The "pragma Convention" might be enough, at least it was when I did some OpenGL programming in Ada, passing Ada vectors or matrices to GL functions. It worked like a charm. > I also wonder if it is generally possible to rationalize other bindings > which involve connecting to C arrays by using (sub)types of the Annex > G.3 vector and matrix types. If not, that would seem to make the Annex > G.3 features useless whenever C array bindings are needed. I can't try (as said, I don't have those Annex G.3-related files), but maybe this works: type C_Real_Vector is new Real_Vector; pragma Convention(C, C_Real_Vector); Though I wonder how the constraint will be handled... Regards, -- (o< | Yves Bailly : http://kafka-fr.net | -o) //\ | Linux Dijon : http://www.coagul.org | //\ \_/ | | \_/` ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to use Annex G.3 Vectors and Matrices in bindings to C arrays 2006-11-12 8:45 ` Yves Bailly @ 2006-11-13 10:48 ` Jerry 0 siblings, 0 replies; 13+ messages in thread From: Jerry @ 2006-11-13 10:48 UTC (permalink / raw) Yves Bailly wrote: > Jerry wrote: > > with arrays which are (sub)typed from the Annex G.3 declarations. For > > example, here is the declaration from the spec of > > Ada.Numerics.Generic_Real_Arrays which is GNAT file a-ngrear.ads: > > Sorry for this off-topic quesiton, but which GNAT version are you using ? > I just can't find this file in GNAT-GPL... > I should have anticipated this. As I understand it, AdaCore has not put the source for the new vector-matrix packages out yet. (I am using a 4.2 that someone on the MacAda.org site has provided, and the sources are not in there.) But I found a nearly-complete set of sources here: http://www.martin.dowie.btinternet.co.uk/ > Have you tried: > type A is array(1..10) of Float; > pragma Convention(C, A); > Please see my reply to the next poster. (However, in GNAT, all arrays are C-compatible, so the use of this pragma is useful only for compatibility. I _hope_ I've used it, however.) > The "pragma Convention" might be enough, at least it was when I did > some OpenGL programming in Ada, passing Ada vectors or matrices to GL > functions. It worked like a charm. > ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to use Annex G.3 Vectors and Matrices in bindings to C arrays 2006-11-12 3:45 How to use Annex G.3 Vectors and Matrices in bindings to C arrays Jerry 2006-11-12 8:45 ` Yves Bailly @ 2006-11-12 19:39 ` Jeffrey R. Carter 2006-11-13 7:09 ` tmoran 2006-11-13 11:20 ` Jerry 1 sibling, 2 replies; 13+ messages in thread From: Jeffrey R. Carter @ 2006-11-12 19:39 UTC (permalink / raw) Jerry wrote: > > I wonder if I am incorrect in believing that the binding to C-arrays > need aliased components. Like I said, the reason for that is a little > fuzzy to me right now. But I do know that if I remove the aliased > component requirement from Long_Float_Array_1D the binding will not > compile. What is the error message that you get? Are you taking 'access of components of such arrays? -- Jeff Carter "Crucifixion's a doddle." Monty Python's Life of Brian 82 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to use Annex G.3 Vectors and Matrices in bindings to C arrays 2006-11-12 19:39 ` Jeffrey R. Carter @ 2006-11-13 7:09 ` tmoran 2006-11-13 11:20 ` Jerry 1 sibling, 0 replies; 13+ messages in thread From: tmoran @ 2006-11-13 7:09 UTC (permalink / raw) > > I wonder if I am incorrect in believing that the binding to C-arrays > > need aliased components. Like I said, the reason for that is a little > > fuzzy to me right now. But I do know that if I remove the aliased > > component requirement from Long_Float_Array_1D the binding will not > > compile. > > What is the error message that you get? Are you taking 'access of > components of such arrays? Pending the answer to that very logical question, I'd surmise his code is old and he needed to pass A(A'first)'access to C, ie, to pass a pointer to the first element in the array. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to use Annex G.3 Vectors and Matrices in bindings to C arrays 2006-11-12 19:39 ` Jeffrey R. Carter 2006-11-13 7:09 ` tmoran @ 2006-11-13 11:20 ` Jerry 2006-11-13 17:42 ` Yves Bailly 2006-11-13 19:09 ` Jeffrey R. Carter 1 sibling, 2 replies; 13+ messages in thread From: Jerry @ 2006-11-13 11:20 UTC (permalink / raw) Jeffrey R. Carter wrote: > Jerry wrote: > > > > I wonder if I am incorrect in believing that the binding to C-arrays > > need aliased components. Like I said, the reason for that is a little > > fuzzy to me right now. But I do know that if I remove the aliased > > component requirement from Long_Float_Array_1D the binding will not > > compile. > > What is the error message that you get? Are you taking 'access of > components of such arrays? > I'm afraid I'll have to apologize for not being accurate in my initial post. Indeed, I am not having any problems (as I erroneously claimed) with 1D arrays. The problem arises with 2D arrays, about which I pestered the list earlier. With further apologies for posting a bit more code that I would like, the following is a typical binding that I made in which it was necessary to gain access to 2D C arrays. procedure Mesh_3D_Base_Contour (x, y : Long_Float_Array_1D; -- surface definition points z : in out Long_Float_Array_2D; -- height of surface at definition points Options : Integer; Contour_Levels : Long_Float_Array_1D) is -- levels at which to draw contours package PL_Float_Pointers_Local is new Interfaces.C.Pointers (Index => Integer, Element => Long_Float, Element_Array => Long_Float_Array_1D, Default_Terminator => 0.0); use type PL_Float_Pointers_Local.Pointer; -- as in RM B.3.2 type PL_Float_Pointer_Array_Local is array (Integer range <>) of PL_Float_Pointers_Local.Pointer; -- array of pointers to Long_Floats which represent the first element of each row of z in C-land Index_Of_First_Column : Integer := z'First(2); z_As_Pointers : PL_Float_Pointer_Array_Local (z'range(1)); procedure plmeshc_local(x : PL_Float_Array; y : PL_Float_Array; z : PL_Float_Pointer_Array_Local; nx : Integer; ny : Integer; opt : Integer; clevel : PL_Float_Array; nlevel : PLINT); pragma Import(C, plmeshc_local, "c_plmeshc"); begin for Index in z'range(1) loop z_As_Pointers(Index) := z(Index, Index_Of_First_Column)'access; end loop; plmeshc_local(x, y, z_As_Pointers, x'Length, y'Length, Options, Contour_Levels, Contour_Levels'Length); -- pass z_As_Pointers here rather than z end Mesh_3D_Base_Contour; The related array definitions are: type Long_Float_Array_1D is array (Integer range <>) of aliased Long_Float; type Long_Float_Array_2D is array (Integer range <>, Integer range <>) of aliased Long_Float; The "thin" binding Ada procedure plmeshc is defined: procedure plmeshc(x : PL_Float_Array; y : PL_Float_Array; z : PL_Float_Array_2D; nx : PLINT; ny : PLINT; opt : PLINT; clevel : PL_Float_Array; nlevel : PLINT); pragma Import(C, plmeshc, "c_plmeshc"); And the original C procedure is defined as here: http://plplot.sourceforge.net/docbook-manual/plplot-html-5.6.1/plmeshc.html So it appears that I need to use access variables to mimic the 2D C arrays, but the Annex G.3 Matrix definitions do not have aliased elements. So, if you re-read my original post and substitute "2D" for "1D" my original questions still stand. Jerry ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to use Annex G.3 Vectors and Matrices in bindings to C arrays 2006-11-13 11:20 ` Jerry @ 2006-11-13 17:42 ` Yves Bailly 2006-11-13 19:50 ` Gautier 2006-11-14 5:18 ` Jerry 2006-11-13 19:09 ` Jeffrey R. Carter 1 sibling, 2 replies; 13+ messages in thread From: Yves Bailly @ 2006-11-13 17:42 UTC (permalink / raw) Jerry wrote: > Jeffrey R. Carter wrote: >> Jerry wrote: >> > >> > I wonder if I am incorrect in believing that the binding to C-arrays >> > need aliased components. Like I said, the reason for that is a little >> > fuzzy to me right now. But I do know that if I remove the aliased >> > component requirement from Long_Float_Array_1D the binding will not >> > compile. >> >> What is the error message that you get? Are you taking 'access of >> components of such arrays? >> > I'm afraid I'll have to apologize for not being accurate in my initial > post. Indeed, I am not having any problems (as I erroneously claimed) > with 1D arrays. The problem arises with 2D arrays, about which I > pestered the list earlier. With further apologies for posting a bit > more code that I would like, the following is a typical binding that I > made in which it was necessary to gain access to 2D C arrays. As far as I know, nD arrays (n > 1) in Ada are very different things than nD arrays in C. Basically, a 2D array in C is an array of arrays, but this is not the case in Ada (it *might* be the case, but I guess it's compiler- dependant). So I'm not sure if it's actually possible to correctly pass nD arrays to C code... Back again to my OpenGL code, I did things like this: type Vector is array(1..3) of Float; pragma Convention(C, Vector); type Matrix is array(1..3) of Vector; pragma Convention(C, Matrix); ...and it worked quite well. But maybe this pragma works for nD arrays? I'm quite interested in the answer (I'll test this as soon as I have some time). Regards, -- (o< | Yves Bailly : http://kafka-fr.net | -o) //\ | Linux Dijon : http://www.coagul.org | //\ \_/ | | \_/` ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to use Annex G.3 Vectors and Matrices in bindings to C arrays 2006-11-13 17:42 ` Yves Bailly @ 2006-11-13 19:50 ` Gautier 2006-11-14 5:28 ` Jerry 2006-11-14 5:18 ` Jerry 1 sibling, 1 reply; 13+ messages in thread From: Gautier @ 2006-11-13 19:50 UTC (permalink / raw) Yves Bailly: > So I'm not sure if it's actually possible to correctly pass nD arrays to > C code... Back again to my OpenGL code, I did things like this: > type Vector is array(1..3) of Float; > pragma Convention(C, Vector); > type Matrix is array(1..3) of Vector; > pragma Convention(C, Matrix); > ...and it worked quite well. > > But maybe this pragma works for nD arrays? I'm quite interested in the > answer (I'll test this as soon as I have some time). This is at least mentioned in the B.1 annex (verse 2), with exactly the example of a nD array's storage. BTW, in my OpenGL code (GLOBE_3D.Math, body) there is... type Matrix_44 is array(0..3,0..3) of aliased Real; -- for GL.MultMatrix pragma Convention(Fortran, Matrix_44); -- GL stores matrices columnwise HTH, Gautier ______________________________________________________________ Ada programming -- http://www.mysunrise.ch/users/gdm/gsoft.htm NB: For a direct answer, e-mail address on the Web site! ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to use Annex G.3 Vectors and Matrices in bindings to C arrays 2006-11-13 19:50 ` Gautier @ 2006-11-14 5:28 ` Jerry 0 siblings, 0 replies; 13+ messages in thread From: Jerry @ 2006-11-14 5:28 UTC (permalink / raw) Gautier wrote: > Yves Bailly: > > > So I'm not sure if it's actually possible to correctly pass nD arrays to > > C code... Back again to my OpenGL code, I did things like this: > > type Vector is array(1..3) of Float; > > pragma Convention(C, Vector); > > type Matrix is array(1..3) of Vector; > > pragma Convention(C, Matrix); > > ...and it worked quite well. > > > > But maybe this pragma works for nD arrays? I'm quite interested in the > > answer (I'll test this as soon as I have some time). > > This is at least mentioned in the B.1 annex (verse 2), with exactly the > example of a nD array's storage. > But that works only for constrained arrays--see my reply to Yves for more detail. The whole problem with interfacing to 2D C arrays is that they are constructed as arrays of pointers to other arrays. In Ada, we can mimic this with an unconstrained array of access variables to other other unconstrained arrays of Long_Floats--therein lies the nastiness. > BTW, in my OpenGL code (GLOBE_3D.Math, body) there is... > > type Matrix_44 is array(0..3,0..3) of aliased Real; -- for GL.MultMatrix > pragma Convention(Fortran, Matrix_44); -- GL stores matrices columnwise > Jerry ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to use Annex G.3 Vectors and Matrices in bindings to C arrays 2006-11-13 17:42 ` Yves Bailly 2006-11-13 19:50 ` Gautier @ 2006-11-14 5:18 ` Jerry 1 sibling, 0 replies; 13+ messages in thread From: Jerry @ 2006-11-14 5:18 UTC (permalink / raw) Yves Bailly wrote: > Jerry wrote: > > So I'm not sure if it's actually possible to correctly pass nD arrays to > C code... Back again to my OpenGL code, I did things like this: > type Vector is array(1..3) of Float; > pragma Convention(C, Vector); > type Matrix is array(1..3) of Vector; > pragma Convention(C, Matrix); > ...and it worked quite well. > > But maybe this pragma works for nD arrays? I'm quite interested in the > answer (I'll test this as soon as I have some time). > Yes, I believe that this should work for constrained arrays. Unfortunately, the plotter software PLplot (and indeed, any plotter program) does not know the size of the arrays and so must receive unconstrained arrays. Ada does not allow arrays which have unconstrained element types. So, modifying your example above, one would have type Vector is array (Integer range <>) of Float; which is OK, but then one would want type Matrix is array (Integer range <>) of Vector; which is not allowed because Vector is an unconstrained type. Jerry ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to use Annex G.3 Vectors and Matrices in bindings to C arrays 2006-11-13 11:20 ` Jerry 2006-11-13 17:42 ` Yves Bailly @ 2006-11-13 19:09 ` Jeffrey R. Carter 2006-11-14 7:31 ` Jerry 2006-11-14 7:54 ` Jerry 1 sibling, 2 replies; 13+ messages in thread From: Jeffrey R. Carter @ 2006-11-13 19:09 UTC (permalink / raw) Jerry wrote: >> > I'm afraid I'll have to apologize for not being accurate in my initial > post. Indeed, I am not having any problems (as I erroneously claimed) > with 1D arrays. The problem arises with 2D arrays, about which I > pestered the list earlier. With further apologies for posting a bit > more code that I would like, the following is a typical binding that I > made in which it was necessary to gain access to 2D C arrays. OK. > z : in out Long_Float_Array_2D; -- height of surface > at definition points I don't see why this is in out. > package PL_Float_Pointers_Local is new Interfaces.C.Pointers > (Index => Integer, > Element => Long_Float, > Element_Array => Long_Float_Array_1D, > Default_Terminator => 0.0); > use type PL_Float_Pointers_Local.Pointer; -- as in RM B.3.2 > type PL_Float_Pointer_Array_Local is array (Integer range <>) of > PL_Float_Pointers_Local.Pointer; -- array of pointers to Long_Floats > which represent the first element of each row of z in C-land > > Index_Of_First_Column : Integer := z'First(2); > z_As_Pointers : PL_Float_Pointer_Array_Local (z'range(1)); > > procedure > plmeshc_local(x : PL_Float_Array; y : PL_Float_Array; z : > PL_Float_Pointer_Array_Local; nx : Integer; ny : Integer; opt : > Integer; clevel : PL_Float_Array; nlevel : PLINT); > pragma Import(C, plmeshc_local, "c_plmeshc"); > > begin > for Index in z'range(1) loop > z_As_Pointers(Index) := z(Index, Index_Of_First_Column)'access; To do this, Z must have aliased components. If you want to use the language-defined matrix type for this, you'll have to copy the values from Z into a local array. I'd probably do something like type Row_Of_Z is new Vector (Z'range (2) ); pragma Convention (C, Row_Of_Z); type Row_Ptr is access all Row_Of_Z; pragma Convention (C, Row_Ptr); type Z_For_C is array (Z'range (1) ) of Row_Ptr; pragma Convention (C, Z_For_C); Z_Ptr : Z_For_C; for I in Z_Ptr'range loop Z_Ptr := new Row_Of_Z; for J in Z'Ptr (I)'range loop Z_Ptr (J) := Z (I, J); end loop; end loop; -- Call C with Z_Ptr -- Free Z_Ptr You could, of course, put the rows into an array of aliased Row_Of_Z and use the 'access of its elements to fill Z_Ptr. That would eliminate the need to free the pointers. A messy way, that doesn't involve copying the elements, is to instantiate System.Address_To_Access_Conversions, and derive a convention-C access type from the access type defined in the instantiation. Then you take 'Address, convert it to an access type using To_Pointer, then convert that to your convention-C access type and store it in your array of pointers. (This is equivalent to using GNAT's 'Unrestricted_Access, but portable.) > The related array definitions are: > type Long_Float_Array_1D is array (Integer range <>) of aliased > Long_Float; > type Long_Float_Array_2D is array (Integer range <>, Integer range > <>) of aliased Long_Float; > > The "thin" binding Ada procedure plmeshc is defined: > procedure plmeshc(x : PL_Float_Array; y : PL_Float_Array; z : > PL_Float_Array_2D; nx : PLINT; ny : PLINT; opt : PLINT; > clevel : PL_Float_Array; nlevel : PLINT); > pragma Import(C, plmeshc, "c_plmeshc"); The declarations of the PL_... types would be useful, too, though we can make a good guess from the C. -- Jeff Carter "Now go away or I shall taunt you a second time." Monty Python & the Holy Grail 07 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to use Annex G.3 Vectors and Matrices in bindings to C arrays 2006-11-13 19:09 ` Jeffrey R. Carter @ 2006-11-14 7:31 ` Jerry 2006-11-14 7:54 ` Jerry 1 sibling, 0 replies; 13+ messages in thread From: Jerry @ 2006-11-14 7:31 UTC (permalink / raw) Jeffrey R. Carter wrote: > > > The related array definitions are: > > type Long_Float_Array_1D is array (Integer range <>) of aliased > > Long_Float; > > type Long_Float_Array_2D is array (Integer range <>, Integer range > > <>) of aliased Long_Float; > > > > The "thin" binding Ada procedure plmeshc is defined: > > procedure plmeshc(x : PL_Float_Array; y : PL_Float_Array; z : > > PL_Float_Array_2D; nx : PLINT; ny : PLINT; opt : PLINT; > > clevel : PL_Float_Array; nlevel : PLINT); > > pragma Import(C, plmeshc, "c_plmeshc"); > > The declarations of the PL_... types would be useful, too, though we can > make a good guess from the C. > They are: subtype PL_Float_Array is My_Common.Long_Float_Array_1D; My_Common is with-ed and defines Long_Float_Array_1D as above. subtype PLINT is Integer; I'm still chewing on the address-to-access idea. It may not be elegant or Ada-like but I want to get a general solution to this 2D array - to - C problem that doesn't have such a speed hit as copying things. For plotting it might not be too much of an issue but I suspect that I'll have to face this again in the GNU Scientific Library binding and the speed issue is more important there. Thanks, Jerry ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: How to use Annex G.3 Vectors and Matrices in bindings to C arrays 2006-11-13 19:09 ` Jeffrey R. Carter 2006-11-14 7:31 ` Jerry @ 2006-11-14 7:54 ` Jerry 1 sibling, 0 replies; 13+ messages in thread From: Jerry @ 2006-11-14 7:54 UTC (permalink / raw) Jeffrey R. Carter wrote: > > > z : in out Long_Float_Array_2D; -- height of surface > > at definition points > > I don't see why this is in out. > When I make it "in" compiler says "access-to-variable designates constant." Jerry ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2006-11-14 7:54 UTC | newest] Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2006-11-12 3:45 How to use Annex G.3 Vectors and Matrices in bindings to C arrays Jerry 2006-11-12 8:45 ` Yves Bailly 2006-11-13 10:48 ` Jerry 2006-11-12 19:39 ` Jeffrey R. Carter 2006-11-13 7:09 ` tmoran 2006-11-13 11:20 ` Jerry 2006-11-13 17:42 ` Yves Bailly 2006-11-13 19:50 ` Gautier 2006-11-14 5:28 ` Jerry 2006-11-14 5:18 ` Jerry 2006-11-13 19:09 ` Jeffrey R. Carter 2006-11-14 7:31 ` Jerry 2006-11-14 7:54 ` Jerry
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox