Path: utzoo!attcan!uunet!mcvax!hp4nl!philmds!leo From: leo@philmds.UUCP (Leo de Wit) Newsgroups: comp.lang.c Subject: Re: Descriptors in VMS C (was Re: VMS C & records in files) Message-ID: <767@philmds.UUCP> Date: 26 Aug 88 21:07:26 GMT References: <612@philmds.UUCP> <1003@nmtsun.nmt.edu> Reply-To: leo@philmds.UUCP (Leo de Wit) Organization: Philips I&E DTS Eindhoven Lines: 92 In article <1003@nmtsun.nmt.edu> warner%hydrovax@nmt.edu (M. Warner Losh) writes: >In article <612@philmds.UUCP>, leo@philmds.UUCP (Leo de Wit) writes... [my stuff conceirning $DESCRIPTOR macro deleted]... >This macro can only be used when you know what the string is that you are >dealing with in advance. While this is true for a large number of cases, >it isn't true in ALL cases. True; the char ptr must be an array, since sizeof is used. [some of Warner's stuff deleted]... > You can >use the function I posted, or you could write a macro that looks something >like: > >#define fill_in_desc(d,s) {d->dsc$w_length = strlen(s); \ > d->dsc$a_address = s;} >and use it like this: > >func(str) >char *str; >{ > $DESCRIPTOR(user_string_dsc, ""); > > fill_in_desc(user_string_dsc, str); >} > >and that would also take care of the problem of freeing stuff up, since it >is done by the 'C' compiler via automatic variables. So this would be an >even better solution than the function that I posted. Leo, thank you for >pointing out this macro. It made me rethink some of the methods that I was >using. > >Warner warner%hydrovax%nmt@relay.cs.net >My spelling and views are my own. There are still some drawbacks: if you use automatic variables, you still have to declare them (for instance by the $DESCRIPTOR macro) and fill them (for instance by the macro you suggested). It can be done all at once however (oh, how I love C 8-): Suppose you need to build such a string descriptor from a (C type) string str, and have to pass the address of this struct (to a VMS system call). This should do the trick: LIB$SOMETHING(&make_descr_s(str)); where make_descr_s is defined by: struct dsc$descriptor_s make_descr_s(str) char *str; { struct dsc$descriptor_s retval; retval.dsc$w_length = strlen(str); retval.dsc$b_dtype = DSC$K_DTYPE_T; retval.dsc$b_class = DSC$K_CLASS_S; retval.dsc$a_pointer = str; return retval; } Note that make_descr_s returns a struct on the stack; the VMS library function will get a pointer to this struct by passing the address (&). It would do you no good by typing make_descr_s as a struct dsc$descriptor_s *, and returning the address of retval, since retval, being an automatic variable, will be gone when make_descr_s returns. In the case retval is declared as static, this WILL work, but you get trouble when using multiple instances of make_descr_s in one parameter list: all values returned will point to the same static buffer (containing the last created descriptor). For instance (supposing make_descr_s returns a pointer to a static struct): LIB$OTHERTHING(make_descr_s(str1),make_descr_s(str2)); will fail. So the solution given seems pretty neat. You could even say #define Make_Str_Descr(str) &make_descr_s(str) and use LIB$SOMETHING(Make_Str_Descr(str)); if you don't like the & in the arg list (but I don't recommend that practice, since it does not really clear things up). Leo.