Descriptors in VMS C (was Re: VMS C & records in files)
Leo de Wit
leo at philmds.UUCP
Sat Aug 27 07:07:26 AEST 1988
In article <1003 at nmtsun.nmt.edu> warner%hydrovax at nmt.edu (M. Warner Losh) writes:
>In article <612 at philmds.UUCP>, leo at 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 at 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.
More information about the Comp.lang.c
mailing list