warner%hydrovax@nmt.edu (M. Warner Losh) (08/25/88)
In article <612@philmds.UUCP>, leo@philmds.UUCP (Leo de Wit) writes... > >Don't know which version of VMS C you're using, but this is from >descrip.h on our system, the last 5 lines (maybe you overlooked them): > [$DESCRITOR 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. For example, if you want to translate the logical name TT, you can do something like: $DESCRIPTOR (tt_dsc, "TT); /* system call to translate logical name */ but if you want to see if some user is on the system (not know at compile time) for a program like TALK or PHONE then you have to generate the descriptor somehow. You can use the $DESCRIPTOR macro to set up the storage, but you'd still have to fill in an address and length. 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.
leo@philmds.UUCP (Leo de Wit) (08/27/88)
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.