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,6c7be346cfa17c37 X-Google-Attributes: gid103376,public From: Sandy McPherson Subject: Re: Ada/Motif problem... Date: 1996/09/02 Message-ID: <322B017D.2F32@wgs.estec.esa.nl> X-Deja-AN: 178001905 references: <4vupg6$ljf@goanna.cs.rmit.edu.au> <01bb94d3$613fc4c0$328371a5@dhoossr.iquest.com> <5058l4$id5@goanna.cs.rmit.edu.au> cc: Dale Stanbrough content-type: text/plain; charset=us-ascii organization: European Space Agency mime-version: 1.0 newsgroups: comp.lang.ada x-mailer: Mozilla 3.0 (X11; I; SunOS 5.4 sun4) Date: 1996-09-02T00:00:00+00:00 List-Id: Dale Stanbrough wrote: > > "Nah. The best idea is to start using Ada95 and use the _standard_ out > of the box interoperability of Interfaces.C.Strings which does all this > (and more)." > > > Interfaces.C.Strings lets me create a copy of the Ada string, and pass > a pointer to that copy. The callback can then make an Ada string from this > copy. This all seems rather expensive, as well as only being by value. > > Is there any way to pass the string _by reference_ in a manner that is > reasonably portable (even with the use of unchecked conversion). I'm > really looking for a way of getting a pointer to the string somehow > that is compatable with size of C pointers. > > Dale This however misses an important point. You don't need to covert to/from C compatible strings to pass data to a callback, the user data passed to the AddCallback function is not used by Motif it is simply passed through, to the callback. Motif does not use this data. Most of the previous posters immediatley assumed that you were in a SetValues/GetValues context, where the string needs to/will be an ASCIZ (null terminated ascii string). The type XtPointer is equivalent to an address. It is easy to convert a string to its address, convert that to XtPointer using UNCHECKED_CONVERSION and then pass it to the AddCallback function. The problem however is how you convert back from the address in the callback and it is different for constrained and unconstrained types. The simplest method is to use/create a type which is constrained and known to both the caller of XtAddCallback and to the callback itself. This is because you have to get back to where you began, which is easy if you have a constrained type, but a bit more complicated if it is unconstrained: normally constrained array types are passed by reference and the implementation of the access type is purely an address, whereas unconstrained types are usually passed by a more complex method and the access type is analogous. In Ada'95 converting string access -> XtPointer -> string access, using UNCHECKED_CONVERSION should be trivial I tried to do this in Ada a few years ago and failed miserably because it was not possible to use an access type on a statically declared object, so I had to resort to buggering around with addresses to get the desired effect. (However, at this point we decided to write our GUI control software in C and the rest of the application in Ada) I have a feeling however if one does (something along the lines of) the following, it might be possible to handle the unconstrained strings by converting the address (or the access type) of the unconstrained string access to an XtPointer (I assume this is an access type which is simply an address, otherwise Motif would choke on it). type USTRING_ACCESS is access STRING; function TO_XT_POINTER( P: SYSTEM'ADDRESS ) return XtPointer is new UNCHECKED_CONVERSION; function FROM_XT_POINTER( P: XtPointer ) return SYSTEM'ADDRESS is new UNCHECKED_CONVERSION; in the function calling AddCallback you can do hellod : USTRING_ACCESS := "Hello World"'ACESSS; ptr : XtPointer := TO_XT_POINTER( hellod'ADDRESS ); and in the callback fix the address of a USTRING_ACCESS variable at the address given by the XtPointer hellod : USTRING_ACCESS; for hellod at FROM_XT_POINTER( ptr ); This is really horrific I know, but it is a fact of life that C and Ada do not mix well. If multiple indirection is possible using type USTRING_ACCESS is access STRING; type USTRING_ACCESS_ACCESS is access USTRING_ACCESS; function TO_XT_POINTER( P: USTRING_ACCESS_ACCESS ) return XtPointer is new UNCHECKED_CONVERSION; function FROM_XT_POINTER( P: XtPointer ) return USTRING_ACCESS_ACCESS is new UNCHECKED_CONVERSION; and USTRING_ACCESS_ACCESS reduces to an address then you might be able to construct something more elegant! e.g. hellod : USTRING_ACCESS := "Hello World"'ACCESS; ptr : XtPointer := TO_XT_POINTER( hellod'ACCESS ); and hellod : USTRING_ACCESS = FROM_XT_POINTER( ptr ); I do not have access to an Ada compiler, or a reference manual, so I take no responsibility for any (obvious) flaws, and I have never used Ada'95 so I'm not sure of the syntax for dereferencing access type. Anyone brave enough to try this will just have to "suck it and see". "Loud clearing of throat follows" Of course having shown it is not necessary to null terminate the string to have it passed to the callback, you have to null terminate it within the callback if you wish to do anything useful with it: i.e. pass it to a Motif function. -- Sandy McPherson MBCS CEng. tel: +31 71 565 4288 (w) ESTEC/WAS P.O. Box 299 NL-2200AG Noordwijk