Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!utgpu!water!watmath!clyde!rutgers!mit-eddie!uw-beaver!tektronix!teklds!copper!stevesu From: stevesu@copper.UUCP Newsgroups: comp.lang.c Subject: Re: Fortran vs. C strings Message-ID: <1142@copper.TEK.COM> Date: Fri, 19-Jun-87 01:14:41 EDT Article-I.D.: copper.1142 Posted: Fri Jun 19 01:14:41 1987 Date-Received: Sat, 20-Jun-87 07:34:44 EDT References: <6480@dartvax.UUCP> Organization: Tektronix Inc., Beaverton, Or. Lines: 83 Summary: Use descriptors I was going to reply by mail as requested, but since misinformation has already been posted, I'll present a quick synopsis here. VMS, in spite of its faults, embodies a nice concept called the VAX Calling Standard, which virtually guarantees that programs written in any language can call each other fairly easily. The calling standard describes not only the stack frame (which is implemented by the VAX CALLS and CALLG instructions), but also conventions for passing typed data, which is the responsibility of the various compilers (or, in the case of a low-level high level language like C, the programmer). Character strings are passed by descriptor. A descriptor is an 8-byte structure that looks like this: _______________________________ |__c_l_a_s_s__|__d_t_y_p_e__|_____l_e_n_g_t_h_____| |______________p_o_i_n_t_e_r___________| or, as a C struct: struct descriptor { unsigned short int dsc_length; unsigned char dsc_dtype; unsigned char dsc_class; char *dsc_pointer; }; When passing a string to another routine, it is usually sufficient to fill in the dtype and class as 0. (Purists may wish to use more appropriate values; see references below.) Here is a quick example. SYS$ASSIGN is not written in Fortran, but the descriptor-passing mechanism is the same. #define IO$_WRITEVBLK 0x30 main() { struct descriptor d; short int channel; d.dsc_pointer = "sys$output"; d.dsc_length = 10; d.dsc_dtype = d.dsc_class = 0; sys$assign(&d, &channel, 0, 0); sys$qiow(0, channel, IO$_WRITEVBLK, 0, 0, 0, "Hello, world!\r", 14, 0, 0, 0, 0); } Note that descriptors are almost always passed by reference (struct descriptor *). Passing a descriptor which is to be filled in by the caller, and accepting a descriptor that has been passed by another routine, are trickier because you have to deal with some more unusual descriptor classes, including one in which the string is stored two bytes beyond the pointer, the pointer pointing to a word holding the string's current length. I believe that LIB$ANALYZE_SDESC can be used to deal with arbitrary string descriptors in a general way, without having to know about all of the descriptor classes. There are some header files or something that come with VAXC, DEC's VMS C compiler, that make handling descriptors a bit easier. Steve Summit stevesu@copper.tek.com References: VAX-11 Guide to Creating Modular Library Procedures (Obsolete VMS V3 manual), section 4.5 VAX/VMS Run-Time Library Routines Reference Manual, section 2.6 Introduction to VAX/VMS System Routines, section 2.9.1 Disclaimer: This entire article has of course been concerned solely with VMS-related issues. Strings are passed to and from Fortran programs on Unix in a completely different way.