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.3 required=5.0 tests=BAYES_00,INVALID_MSGID, MSGID_RANDY autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,1726119712bbda0d X-Google-Attributes: gid103376,public From: Jeff Carter Subject: Re: Interfacing to C non-void procedure with "out" parameters Date: 2000/01/14 Message-ID: <85nqaf$95o$1@nnrp1.deja.com>#1/1 X-Deja-AN: 572642229 References: <387f1c30.12554815@news.rdg.ac.uk> <85ngl3$10s$1@nnrp1.deja.com> X-Http-Proxy: 1.0 x32.deja.com:80 (Squid/1.1.22) for client 205.188.200.28 Organization: Deja.com - Before you buy. X-Article-Creation-Date: Fri Jan 14 18:36:00 2000 GMT X-MyDeja-Info: XMYDJUIDjrcarter001 Newsgroups: comp.lang.ada X-Http-User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; AOL 5.0; Windows 95; DigExt; Freei Client 2.1) Date: 2000-01-14T00:00:00+00:00 List-Id: In article <85ngl3$10s$1@nnrp1.deja.com>, Ted Dennison wrote: > In article <387f1c30.12554815@news.rdg.ac.uk>, > For instance, suppose we have the following (made up) C routine: > > int esGetValue (int key, const int *value); > > The idea being that you pass in a key and get back a value for it. The > function returns 1 on success, 0 on failure. > > On the Ada side, we'd much prefer to access this routine thusly: > > Get_Failed : exception; -- raised by Get_Value when the get fails > > function Get_Value (Key : Integer) return Integer; > > First you interface to the routine to create your thin binding: > > function esGetValue (Key : in Interfaces.C.Int; > Value : in System.Address > ) return Interfaces.C.Int; > pragma Import (C, esGetValue, "esGetValue"); > > Note that for the "int *" parameter I used System.Address. This is not > officially portable, but in practice works on every normal platform. You > could instead use a type instantiated from Interfaces.C.Pointers for int > to achieve theoretical portability. There's no reason to use System.Address here. Use an access parameter: function Es_Get_Value (Key : Interfaces.C.Int; Value : access Interfaces.C.Int) return Interfaces.C.Int; pragma Import (C, ...); > > Finally we create our thick binding with the desired interface. > > function Get_Value (Key : Integer) return Integer is > Value : aliased Interfaces.C.Int; > use type Interfaces.C.Int; -- Give access to "=" operator > begin > if > esGetValue > (Key => Interfaces.C.Int(Key), > Value => Value > ) = 0 > then > raise Get_Failed; > end if; > return Integer(Value); > end Get_Value; Note that the call here should not compile; Value is not of type System.Address. With an access parameter, use Value => Value'access and everything should be fine. -- Jeff Carter "Now go away or I shall taunt you a second time." -- Monty Python and the Holy Grail Sent via Deja.com http://www.deja.com/ Before you buy.