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=-0.4 required=5.0 tests=AC_FROM_MANY_DOTS,BAYES_00 autolearn=no autolearn_force=no version=3.4.4 X-Google-Thread: 103376,47957cb8c33729e5 X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news1.google.com!newsread.com!newsprint.newsread.com!tdsnet-transit!newspeer.tds.net!news.glorb.com!cyclone1.gnilink.net!spamkiller2.gnilink.net!gnilink.net!trndny01.POSTED!0f19ed38!not-for-mail From: "Frank J. Lhota" Newsgroups: comp.lang.ada References: <2vjnfbF2lioiaU1@uni-berlin.de> <1Ucld.25101$KJ6.2286@newsread1.news.pas.earthlink.net> Subject: Re: Thick Ada bindings to C Win32 X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2900.2180 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2180 X-RFC2646: Format=Flowed; Original Message-ID: Date: Mon, 29 Nov 2004 14:34:48 GMT NNTP-Posting-Host: 151.203.9.191 X-Complaints-To: abuse@verizon.net X-Trace: trndny01 1101738888 151.203.9.191 (Mon, 29 Nov 2004 09:34:48 EST) NNTP-Posting-Date: Mon, 29 Nov 2004 09:34:48 EST Xref: g2news1.google.com comp.lang.ada:6637 Date: 2004-11-29T14:34:48+00:00 List-Id: "Brian May" wrote in message news:sa4vfbpzgfu.fsf@snoopy.apana.org.au... >>>>>> "Brian" == Brian May writes: > > Brian> I seem to remember that I encountered problems doing things > Brian> as simply as you suggest, but I can't remember why nor can > Brian> I imagine why - I will try it again and report back here > Brian> with details of any errors encountered. > > Unfortunately, I was right, I did have problems: > > type Byte_Array_Access is access all Byte_Array; > pragma Convention (C,Byte_Array_Access); > > produces: > > serial.adb:107:11: warning: this access type does not correspond to C > pointer > > and: > > function To_LPCVOID is new > Ada.Unchecked_Conversion (Byte_Array_Access, Win32.LPCVOID); > > produces: > > serial.adb:144:04: warning: types for unchecked conversion have different > sizes > > So I tried: > > Type Char_Array_Ptr is access all Interfaces.c.Char_Array; > pragma Convention (C,Char_Array_Ptr); > > which produces: > > serial.adb:89:09: warning: this access type does not correspond to C > pointer The reason for this is that Ada needs to keep track of the array bounds of an Byte_Array object. In the case of Byte_Array_Access, the GNAT compiler choose the "fat pointer" approach of including the array bounds as part of the access type. In other words, a Byte_Array_Access object contains a pointer to the bytes, and additional components specifying 'First and 'Last. This is why the pragma Convention stuff failed. You could fix this problem in one of two ways. One way is that use a representation clause to specify the size of a Byte_Array_Access object to be the size of a pointer, e.g. for Byte_Array_Access'Size use 32; This forces GNAT to not include array bounds in a Byte_Array_Access object. A cleaner and more portable approach would be to apply the 'Access attribute to the first element of the array. We can do this using the following definitions: type Byte_Array is array (Positive range <>) of aliased Byte; -- Note the addition of "aliased" type Byte_Array_Access is access all Byte; pragma Convention (C,Byte_Array_Access); By declaring the components of Byte_Array to be aliased, we guarantee that Byte_Array objects will never be packed in such a way that the components are not individually addressable, and hence we are free to apply 'Access or 'Unchecked_Access to the components of a Byte_Array object. Then we define the Byte_Array_Access as a pointer to one of the components. Now assume that we have the object Data : Byte_Array( 1 .. Data_Length ); and that we want to pass it to the subprogram function DoSomethingInC ( lpBytes : in Byte_Array_Access ) return Interfaces.C.Int; pragma Import (C, DoSomethingInC ); then we could do this by applying 'Unchecked_Access to the first component of the array, as follows: Result := DoSomethingInC( lpBytes => Data(Data'First)'Unchecked_Access ); Hope this helps.