From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,d71460587da14d5b X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-08-04 07:33:16 PST Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!news-spur1.maxwell.syr.edu!news.maxwell.syr.edu!newsfeed.icl.net!newsfeed.fjserv.net!news.tele.dk!news.tele.dk!small.news.tele.dk!newsfeed.multikabel.nl!news-x2.support.nl!post.news-service.com!nf1.news-service.com!not-for-mail From: Andreas Almroth Subject: Re: Importing C structs? Date: Mon, 04 Aug 2003 15:33:52 +0100 User-Agent: Pan/0.14.0 (I'm Being Nibbled to Death by Cats!) Message-ID: Newsgroups: comp.lang.ada References: <6RYVa.16208$It4.10081@rwcrnsc51.ops.asp.att.net> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit X-Complaints-To: abuse@news-service.com Organization: News-Service.com X-Trace: 70b703f2e6eaa98ae431525772 Xref: archiver1.google.com comp.lang.ada:41169 Date: 2003-08-04T15:33:52+01:00 List-Id: On Wed, 30 Jul 2003 23:50:26 +0000, tmora wrote: >> type Jpeg_Error_Mgr is record >> ... >> Msg_Parm : System.Address; > > This is wrong. The C has > >> union { >> int i[8]; >> char s[JMSG_STR_PARM_MAX]; >> } msg_parm; > which means msg_parm is JMSG_STR_PARM_MAX number of bytes, interpretable > sometimes as a char array and sometimes as an int array followed by > filler. msg_parm is never an address. To match the C, I suggest making I really never have thought about the padding part, but I now see that when using unions, the C compiler actually pad out to the largest type. Quite logical actually... When mapping unions I usually try to mimic the union in (in GNAT mind you) as in order to get a clearer representation. I got this from "googling" a bit a while ago; type Union_Range is new Positive 1..2; type Some_Union(X : Union_Range := 1) is record case X is when 1 => I : Int_8_Array; when 2 => S : Char_80_Array; end case; end record; pragma Unchecked_Union(Some_Union); type Struct_With_Union is record X : Interfaces.C.Int; Y : Some_Union; Z : Interfaces.C.Double; end record; pragma Convention(C,Struct_With_Union); This has worked quite well so far with GNAT, and no need for manual conversions in the code. I'm curious if this works with other Ada compilers? > msg_parm an interfaces.c.char_array (the larger of the two objects), > and then doing an unchecked_conversion on those (relatively rare) > occasions when you need to treat it as an array of int's. Here's > a compilable example: > > with interfaces.c; > with ada.unchecked_conversion; > procedure testluc is > > JMSG_STR_PARM_MAX: constant := 80; > subtype Msg_Parm_C_Type is Interfaces.C.Char_Array(1 .. JMSG_STR_PARM_MAX); > > subtype I_Part is Interfaces.C.Size_T range 1 .. 32; > subtype Msg_Parm_C_I_Part is Interfaces.C.Char_Array(I_Part); > type Msg_Parm_I_Type is array(1 .. 8) of Interfaces.C.Int; > > function To_I is new Ada.Unchecked_Conversion > (Source=>Msg_Parm_C_I_Part, > Target=>Msg_Parm_I_Type); > > function To_C is new Ada.Unchecked_Conversion > (Source=>Msg_Parm_I_Type, > Target=>Msg_Parm_C_I_Part); > > type Jpeg_Error_Mgr is record > msg_parm: Msg_Parm_C_Type; > end record; > > X : Jpeg_Error_Mgr; > X_I : Msg_Parm_I_Type; > N : Interfaces.C.Int; > > begin > -- fetch ints from X.msg_parm > N := To_I(X.msg_parm(I_Part))(1); > N := To_I(X.msg_parm(I_Part))(2); > -- store ints into X.msg_parm > X_I(1) := 1; > X_I(8) := 2; > X.msg_parm(I_Part):=To_C(X_I); > end testluc; Cheers, Andreas