* Interfacing C type, unconstrained array with record @ 2010-10-16 17:35 Ron Wills 2010-10-16 18:36 ` Dmitry A. Kazakov 0 siblings, 1 reply; 13+ messages in thread From: Ron Wills @ 2010-10-16 17:35 UTC (permalink / raw) Hi all I've started learning Ada and started porting some software I had in C/ C++ as a learning exercise. The software uses SDL, so I started a thin wrapper around it. I've been very successful with it, but with the exception of the palette structure which in C is defined as: typedef struct { int ncolors; SDL_Color colors[]; // Actually is SDL_Color *colors but this is how it is laid out in memory } SDL_Palette; In Ada I'm trying to do something like: type SDL_Color is record r, g, b, unused : Uint8; end; type SDL_Color_Array is array(Positive range <>) of Color; type SDL_Palette is record ncolors : Integer; colors : SDL_Color_Array; end; Now Ada (GNAT) won't compile this because the colors component is unconstrained, which is understandable. I've been googling for a couple of days for a way of modeling this in Ada and still having access to all the colors in the colors component. In other SDL interface implementations, all I've seen is that the colors component is made into a type of "Dummy" component and made more or less useless. I've also been combing the reference manual, but nothing I've noticed seems to solve this issue. I'm sure I'm not the only one that has come across this problem and was wondering what solutions are available. Thanks ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Interfacing C type, unconstrained array with record 2010-10-16 17:35 Interfacing C type, unconstrained array with record Ron Wills @ 2010-10-16 18:36 ` Dmitry A. Kazakov 2010-10-16 19:19 ` Ron Wills 2010-10-16 21:41 ` Robert A Duff 0 siblings, 2 replies; 13+ messages in thread From: Dmitry A. Kazakov @ 2010-10-16 18:36 UTC (permalink / raw) On Sat, 16 Oct 2010 10:35:39 -0700 (PDT), Ron Wills wrote: > Hi all > > I've started learning Ada and started porting some software I had in C/ > C++ as a learning exercise. The software uses SDL, so I started a thin > wrapper around it. I've been very successful with it, but with the > exception of the palette structure which in C is defined as: > > typedef struct { > int ncolors; > SDL_Color colors[]; // Actually is SDL_Color *colors but this is how > it is laid out in memory > } SDL_Palette; > > In Ada I'm trying to do something like: > > type SDL_Color is > record > r, g, b, unused : Uint8; > end; > type SDL_Color_Array is array(Positive range <>) of Color; > type SDL_Palette is > record > ncolors : Integer; > colors : SDL_Color_Array; > end; > > Now Ada (GNAT) won't compile this because the colors component is > unconstrained, which is understandable. I've been googling for a > couple of days for a way of modeling this in Ada and still having > access to all the colors in the colors component. In other SDL > interface implementations, all I've seen is that the colors component > is made into a type of "Dummy" component and made more or less > useless. I've also been combing the reference manual, but nothing I've > noticed seems to solve this issue. I'm sure I'm not the only one that > has come across this problem and was wondering what solutions are > available. You need a flat array, e.g. with Interfaces; use Interfaces; with Interfaces.C; use Interfaces.C; ... type SDL_Color is record R, G, B, Unused : Unsigned_8; end record; pragma Convention (C, SDL_Color); type SDL_Color_Array is array (Positive) of aliased SDL_Color; pragma Convention (C, SDL_Color_Array); type SDL_Palette is record N_Colors : Int; Colors : SDL_Color_Array; end record; pragma Convention (C, SDL_Palette); Now, you cannot directly declare a SDL_Palette variable, because it is too large. You should do it as you would do in C, i.e. allocate some amount of memory and then set structure pointer to it. You do not need 'new' or access types in Ada. It can be on the stack like this: with System.Storage_Elements; use System.Storage_Elements; ... Raw_Memory : Storage_Array (1..1_024); -- Memory Palette : SDL_Palette; for Palette'Address use Raw_Memory'Address; begin Palette.N_Colors := 20; Of course computing memory size from N_Colors is up to you (as in C). -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Interfacing C type, unconstrained array with record 2010-10-16 18:36 ` Dmitry A. Kazakov @ 2010-10-16 19:19 ` Ron Wills 2010-10-16 22:15 ` Jeffrey Carter 2010-10-17 8:35 ` Dmitry A. Kazakov 2010-10-16 21:41 ` Robert A Duff 1 sibling, 2 replies; 13+ messages in thread From: Ron Wills @ 2010-10-16 19:19 UTC (permalink / raw) On Oct 16, 12:36 pm, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de> wrote: > On Sat, 16 Oct 2010 10:35:39 -0700 (PDT), Ron Wills wrote: > > Hi all > > > I've started learning Ada and started porting some software I had in C/ > > C++ as a learning exercise. The software uses SDL, so I started a thin > > wrapper around it. I've been very successful with it, but with the > > exception of the palette structure which in C is defined as: > > > typedef struct { > > int ncolors; > > SDL_Color colors[]; // Actually is SDL_Color *colors but this is how > > it is laid out in memory > > } SDL_Palette; > > > In Ada I'm trying to do something like: > > > type SDL_Color is > > record > > r, g, b, unused : Uint8; > > end; > > type SDL_Color_Array is array(Positive range <>) of Color; > > type SDL_Palette is > > record > > ncolors : Integer; > > colors : SDL_Color_Array; > > end; > > > Now Ada (GNAT) won't compile this because the colors component is > > unconstrained, which is understandable. I've been googling for a > > couple of days for a way of modeling this in Ada and still having > > access to all the colors in the colors component. In other SDL > > interface implementations, all I've seen is that the colors component > > is made into a type of "Dummy" component and made more or less > > useless. I've also been combing the reference manual, but nothing I've > > noticed seems to solve this issue. I'm sure I'm not the only one that > > has come across this problem and was wondering what solutions are > > available. > > You need a flat array, e.g. > > with Interfaces; use Interfaces; > with Interfaces.C; use Interfaces.C; > ... > type SDL_Color is record > R, G, B, Unused : Unsigned_8; > end record; > pragma Convention (C, SDL_Color); > type SDL_Color_Array is array (Positive) of aliased SDL_Color; > pragma Convention (C, SDL_Color_Array); > type SDL_Palette is record > N_Colors : Int; > Colors : SDL_Color_Array; > end record; > pragma Convention (C, SDL_Palette); The "pragma Convention" did the trick! I must say, Ada is the one language I've encountered that seems to have the largest learning curve because of the most cryptic references I ever seen ;) > Now, you cannot directly declare a SDL_Palette variable, because it is too > large. You should do it as you would do in C, i.e. allocate some amount of > memory and then set structure pointer to it. You do not need 'new' or > access types in Ada. It can be on the stack like this: > > with System.Storage_Elements; use System.Storage_Elements; > ... > Raw_Memory : Storage_Array (1..1_024); -- Memory > Palette : SDL_Palette; > for Palette'Address use Raw_Memory'Address; > begin > Palette.N_Colors := 20; > > Of course computing memory size from N_Colors is up to you (as in C). Thanks for the tip, but I don't actually need to allocate any palette records (this should never be done). The palette is a read-only field within the pixel information structure of a surface. I just need this record definition to define the constant access pointer to be able to access the palette information. Many thanks, now I move forward again :D > -- > Regards, > Dmitry A. Kazakovhttp://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Interfacing C type, unconstrained array with record 2010-10-16 19:19 ` Ron Wills @ 2010-10-16 22:15 ` Jeffrey Carter 2010-10-17 10:20 ` Simon Wright 2010-10-17 8:35 ` Dmitry A. Kazakov 1 sibling, 1 reply; 13+ messages in thread From: Jeffrey Carter @ 2010-10-16 22:15 UTC (permalink / raw) On 10/16/2010 12:19 PM, Ron Wills wrote: > > The "pragma Convention" did the trick! I must say, Ada is the one > language I've encountered that seems to have the largest learning > curve because of the most cryptic references I ever seen ;) You should probably finish learning Ada before trying to do stuff like interfacing with C. Then you'd realize the "cryptic references" are all due to C. -- Jeff Carter "Crucifixion's a doddle." Monty Python's Life of Brian 82 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Interfacing C type, unconstrained array with record 2010-10-16 22:15 ` Jeffrey Carter @ 2010-10-17 10:20 ` Simon Wright 2010-10-17 12:38 ` Robert A Duff 0 siblings, 1 reply; 13+ messages in thread From: Simon Wright @ 2010-10-17 10:20 UTC (permalink / raw) Jeffrey Carter <spam.jrcarter.not@spam.not.acm.org> writes: > On 10/16/2010 12:19 PM, Ron Wills wrote: >> >> The "pragma Convention" did the trick! I must say, Ada is the one >> language I've encountered that seems to have the largest learning >> curve because of the most cryptic references I ever seen ;) > > You should probably finish learning Ada before trying to do stuff like > interfacing with C. Then you'd realize the "cryptic references" are > all due to C. I agree about the cryptic references being because of C, but .. people normally start on a new language because they have a project in mind and it seems like a possible fit; and if that project involves interfacing with C, that's where they're going to begin. Personally (but them I've been doing this for a while) I found the ARM sections on interfacing pragmas (http://www.adaic.com/standards/05rm/html/RM-B-1.html) and interfacing with C and C++ (http://www.adaic.com/standards/05rm/html/RM-B-3.html) clear -- except that I started at the second, and only found the link to the first half-way down the page. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Interfacing C type, unconstrained array with record 2010-10-17 10:20 ` Simon Wright @ 2010-10-17 12:38 ` Robert A Duff 0 siblings, 0 replies; 13+ messages in thread From: Robert A Duff @ 2010-10-17 12:38 UTC (permalink / raw) Simon Wright <simon@pushface.org> writes: > I agree about the cryptic references being because of C, but .. people > normally start on a new language because they have a project in mind and > it seems like a possible fit; and if that project involves interfacing > with C, that's where they're going to begin. True, but interfacing between languages is inherently complicated, and inherently dangerous. Ada has pretty good support in this area compared to most other languages (most of which entirely ignore the issue). That makes Ada more complicated, but also more useful. - Bob ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Interfacing C type, unconstrained array with record 2010-10-16 19:19 ` Ron Wills 2010-10-16 22:15 ` Jeffrey Carter @ 2010-10-17 8:35 ` Dmitry A. Kazakov 2010-10-17 12:30 ` Robert A Duff 1 sibling, 1 reply; 13+ messages in thread From: Dmitry A. Kazakov @ 2010-10-17 8:35 UTC (permalink / raw) On Sat, 16 Oct 2010 12:19:18 -0700 (PDT), Ron Wills wrote: > The "pragma Convention" did the trick! I must say, Ada is the one > language I've encountered that seems to have the largest learning > curve because of the most cryptic references I ever seen ;) What you are doing is interfacing to another language. That is not Ada, but system programming. If you think pragma Convention cryptic, well, what about reading the compiler manual for call stack frame format details and implementing that using Assembler code insertions? (:-)) P.S. to dear ARG members. Why discrimnants cannot be mapped onto components of a C structure. I mean making OK this: type Vector is array (size_t range <>) of Whatever; � �pragma Convention (C, Vector); � �type Constrained (Size : size_t) is record � � �List� : Vector (1..Size); � �end record; � �pragma Convention (C, Constrained); -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Interfacing C type, unconstrained array with record 2010-10-17 8:35 ` Dmitry A. Kazakov @ 2010-10-17 12:30 ` Robert A Duff 0 siblings, 0 replies; 13+ messages in thread From: Robert A Duff @ 2010-10-17 12:30 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > On Sat, 16 Oct 2010 12:19:18 -0700 (PDT), Ron Wills wrote: > >> The "pragma Convention" did the trick! I must say, Ada is the one >> language I've encountered that seems to have the largest learning >> curve because of the most cryptic references I ever seen ;) > > What you are doing is interfacing to another language. That is not Ada, but > system programming. If you think pragma Convention cryptic, well, what > about reading the compiler manual for call stack frame format details and > implementing that using Assembler code insertions? (:-)) Good point. And what about reading the C standard to find all the good features for interfacing to Ada (or to any other language)? That's easy -- there are no such features! > P.S. to dear ARG members. Why discrimnants cannot be mapped onto components > of a C structure. I mean making OK this: > > type Vector is array (size_t range <>) of Whatever; > � �pragma Convention (C, Vector); > � �type Constrained (Size : size_t) is record > � � �List� : Vector (1..Size); > � �end record; > � �pragma Convention (C, Constrained); Well, in fact I think that will work in GNAT, although it will warn about the fact that C doesn't have discriminants. But this is tricky. The C code depends on the fact that the List component comes last. There is no such requirement in Ada that discriminant-dependent fields come last (either in the declaration, or in the memory layout). What if there were two discriminants, and two discriminant-dependent arrays? That doesn't match anything on the C side. Many compilers use extra dope when there are discriminants or unconstrained arrays. Ada 83 didn't have very good support for interfacing -- most of this stuff was invented for Ada 95. But by that time, compilers already existed, and the compiler writers didn't want to change the "dope". For example, I know of one compiler that would store the size (in bytes) of the above record (in addition to the Size field, which is the length of that array). Whether that's a good idea is arguable, but it has the advantage that block "=" and ":=" don't have to calculate the size in bytes. And it's just a special case of storing the offset of each discriminant-dependent component (to avoid recalculating those) -- the size is just the offset of the end. (By the way, I prefer to use "size" to refer to memory sizes, measured in bits, bytes, words, or whatever, and use "length" to refer to array lengths, measured in number of components. The latter is a higher-level concept.) Anyway, I guess the real answer to your question is, C doesn't have discriminants, so nobody thought it would be a good idea to require interfacing discriminants to something in C. It could make sense, but only in very limited cases. Compilers are allowed to support it, but there's no portable (language defined) support. - Bob ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Interfacing C type, unconstrained array with record 2010-10-16 18:36 ` Dmitry A. Kazakov 2010-10-16 19:19 ` Ron Wills @ 2010-10-16 21:41 ` Robert A Duff 2010-10-16 23:34 ` tmoran ` (2 more replies) 1 sibling, 3 replies; 13+ messages in thread From: Robert A Duff @ 2010-10-16 21:41 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > You need a flat array, e.g. > > with Interfaces; use Interfaces; > with Interfaces.C; use Interfaces.C; I'd probably write: with Interfaces.C; use Interfaces; and then refer to C.int instead of Int. No big deal. > type SDL_Color is record > R, G, B, Unused : Unsigned_8; > end record; > pragma Convention (C, SDL_Color); > type SDL_Color_Array is array (Positive) of aliased SDL_Color; I think you want this indexed by the same type as N_Colors. And why does it need to have aliased components? So perhaps: type SDL_Color_Array is array (Int range 1..1_000_000) of SDL_Color; > pragma Convention (C, SDL_Color_Array); > type SDL_Palette is record > N_Colors : Int; > Colors : SDL_Color_Array; > end record; > pragma Convention (C, SDL_Palette); > > Now, you cannot directly declare a SDL_Palette variable, because it is too > large. You should do it as you would do in C, i.e. allocate some amount of > memory and then set structure pointer to it. You do not need 'new' or > access types in Ada. It can be on the stack like this: > > with System.Storage_Elements; use System.Storage_Elements; > ... > Raw_Memory : Storage_Array (1..1_024); -- Memory > Palette : SDL_Palette; > for Palette'Address use Raw_Memory'Address; I think you need to worry about alignment here. Perhaps: pragma Assert(SDL_Palette'Alignment = C.int'Alignment); for Raw_Memory'Alignment use C.int'Alignment; > begin > Palette.N_Colors := 20; > > Of course computing memory size from N_Colors is up to you (as in C). You might want to say: Colors: SDL_Color_Array renames Palette.Colors(1..Palette.N_Colors); and then refer to components of Colors, so you get array bounds checking. - Bob ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Interfacing C type, unconstrained array with record 2010-10-16 21:41 ` Robert A Duff @ 2010-10-16 23:34 ` tmoran 2010-10-17 6:59 ` J-P. Rosen 2010-10-17 7:45 ` Dmitry A. Kazakov 2 siblings, 0 replies; 13+ messages in thread From: tmoran @ 2010-10-16 23:34 UTC (permalink / raw) In this particular simple (and common) case, how about translating > typedef struct { > int ncolors; > SDL_Color colors[]; // Actually is SDL_Color *colors but this is how > it is laid out in memory > } SDL_Palette; to type SDL_Palette(ncolors : interfaces.c.int) is record colors : SDL_Color_Array(1 .. ncolors); end record; for SDL_Palette use record ncolors at 0 range 0 .. 31; end record; I don't understand the following comment. "colors" here is actually an array, not a pointer, right? > SDL_Color colors[]; // Actually is SDL_Color *colors but this is how > it is laid out in memory ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Interfacing C type, unconstrained array with record 2010-10-16 21:41 ` Robert A Duff 2010-10-16 23:34 ` tmoran @ 2010-10-17 6:59 ` J-P. Rosen 2010-10-17 12:34 ` Robert A Duff 2010-10-17 7:45 ` Dmitry A. Kazakov 2 siblings, 1 reply; 13+ messages in thread From: J-P. Rosen @ 2010-10-17 6:59 UTC (permalink / raw) Le 16/10/2010 23:41, Robert A Duff a �crit : > "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > >> You need a flat array, e.g. >> >> with Interfaces; use Interfaces; >> with Interfaces.C; use Interfaces.C; > > I'd probably write: > > with Interfaces.C; use Interfaces; > > and then refer to C.int instead of Int. > No big deal. > Nitpicking: nothing prevents you from writing C.int even in the presence of a use clause for Interfaces.C. Although I am quite liberal in using use clauses, I do that quite often when I feel it is more readable. -- --------------------------------------------------------- J-P. Rosen (rosen@adalog.fr) Adalog a d�m�nag� / Adalog has moved: 2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Interfacing C type, unconstrained array with record 2010-10-17 6:59 ` J-P. Rosen @ 2010-10-17 12:34 ` Robert A Duff 0 siblings, 0 replies; 13+ messages in thread From: Robert A Duff @ 2010-10-17 12:34 UTC (permalink / raw) "J-P. Rosen" <rosen@adalog.fr> writes: > Nitpicking: nothing prevents you from writing C.int even in the presence > of a use clause for Interfaces.C. True, but I rarely take advantage of that, and I prefer to say X.Y or Y consistently, not both in the same package. I fixed a bug in GNAT a few days ago, where I ran across code that mixed X.Y and Y, because somebody thought X.Y was more readable, but somebody else just refered to Y because Y happened to be directly visible. No big deal, but the code looked odd to me. > ...Although I am quite liberal in using > use clauses, I do that quite often when I feel it is more readable. - Bob ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Interfacing C type, unconstrained array with record 2010-10-16 21:41 ` Robert A Duff 2010-10-16 23:34 ` tmoran 2010-10-17 6:59 ` J-P. Rosen @ 2010-10-17 7:45 ` Dmitry A. Kazakov 2 siblings, 0 replies; 13+ messages in thread From: Dmitry A. Kazakov @ 2010-10-17 7:45 UTC (permalink / raw) On Sat, 16 Oct 2010 17:41:40 -0400, Robert A Duff wrote: > and then refer to C.int instead of Int. There is no integer but int, and Stroustrup is its prophet! (:-)) -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2010-10-17 12:38 UTC | newest] Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2010-10-16 17:35 Interfacing C type, unconstrained array with record Ron Wills 2010-10-16 18:36 ` Dmitry A. Kazakov 2010-10-16 19:19 ` Ron Wills 2010-10-16 22:15 ` Jeffrey Carter 2010-10-17 10:20 ` Simon Wright 2010-10-17 12:38 ` Robert A Duff 2010-10-17 8:35 ` Dmitry A. Kazakov 2010-10-17 12:30 ` Robert A Duff 2010-10-16 21:41 ` Robert A Duff 2010-10-16 23:34 ` tmoran 2010-10-17 6:59 ` J-P. Rosen 2010-10-17 12:34 ` Robert A Duff 2010-10-17 7:45 ` Dmitry A. Kazakov
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox