vallury@dartvax.UUCP (RustCat) (06/16/87)
Hello, This essentially regards calling a Fortran routine from a C program. To be more specific, I'm trying to do this on the VMS in order to write a C interface for the GKS-Plot10 set of Fortran routines. I have no problems with numbers (ints or floats). This is pretty straightforward. The C source simply needs to pass the addresses of the variables to the Fortran routine and all is fine. Unfortunately, the same doesn't seem to work with strings or character variables. I keep getting stack dumps irrespective of whether I send the string with single quotes, or double quotes around it. There was one other way of doing this and it seemed to partially work. That is as follows: In the C source code, I use the following scheme, extern char[30] GKString; strcpy (GKString, "..."); Fortran_Routine (); And in the corresponding Fortran routine, COMMON/GKString/MyString ... In this case, I don't get the stack dumps, but the string simply doesn't seem to be getting transmitted to the GKS plotting routine (GTX for example) properly. Would this be due to some sort of string terminator syntax difference between the two languages? Once again, I've tried enclosing the string both in single and double quotes but it doesn't work. Have any of you come across this problem before? And managed to get over it? This IS on the VMS and I guess the Unix format for external language addressing might not work. I'd appreciate any possible solutions or pointers to tackling these 2 related problems, namely 1) how to pass string variables directly and 2) the actual representation of strings (and terminators) between the two languages. E-mail would probably be preferable since I don't spend too much time on here these days. Thank you. Vallury vallury@dartcms1.BITNET vallury@dartvax.UUCP
edw@ius2.cs.cmu.edu (Eddie Wyatt) (06/17/87)
In Fortrash, Integers are actually longs (if you pass pointers to integers instead of pointers to longs and have it still work, it is because sizeof(int) == sizeof(long) on the machine you are working on) Fortrash strings (I think) have the format first four(?) bytes holds the size of the string followed by the characters in the string. -- Eddie Wyatt e-mail: edw@ius2.cs.cmu.edu
riddle@woton.UUCP (06/18/87)
In article <1202@ius2.cs.cmu.edu>, edw@ius2.cs.cmu.edu (Eddie Wyatt) writes: > > Fortrash strings (I think) have the format first four(?) bytes > holds the size of the string followed by the characters in the string. This is compiler-dependent. As I recall, Microsoft Fortran (to name one example) has two types of character constants, one for use within Fortran and one for use when interfacing with C. The former has no accessible length information or final delimiter stored with it at all, at least not that I could find; the latter uses a C-style final null as a delimiter. When you program in Microsoft Fortran, you indicate that you want a C-style string by appending a C to it after the final quote (e.g. 'foobar'C). This is an awkward solution to the problem, but it works. Other compilers may not provide any solution at all. --- Prentiss Riddle ("Aprendiz de todo, maestro de nada.") --- Opinions expressed are not necessarily those of Shriners Burns Institute. --- riddle@woton.UUCP {ihnp4,harvard,seismo}!ut-sally!im4u!woton!riddle
stevesu@copper.UUCP (06/19/87)
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.
drw@cullvax.UUCP (Dale Worley) (06/19/87)
edw@ius2.cs.cmu.edu (Eddie Wyatt) writes: > In Fortrash, Integers are actually longs (if you pass pointers to > integers instead of pointers to longs and have it still work, it is because > sizeof(int) == sizeof(long) on the machine you are working on) I'm somewhat bothered that none of you are specifying which implementations of the two languages you are discussing. When you want to interface two different language systems, you have to figure out how both of them map the language structures to machine code, and figure out the right hacks to get the information across. In any case, the particular solution will only be good for the two language implementations involved. Dale -- Dale Worley Cullinet Software ARPA: cullvax!drw@eddie.mit.edu UUCP: ...!seismo!harvard!mit-eddie!cullvax!drw If you light a match, how much mass does it convert into energy?
edw@ius2.cs.cmu.edu (Eddie Wyatt) (06/20/87)
In article <1299@cullvax.UUCP>, drw@cullvax.UUCP (Dale Worley) writes: > edw@ius2.cs.cmu.edu (Eddie Wyatt) writes: > > In Fortrash, Integers are actually longs (if you pass pointers to > > integers instead of pointers to longs and have it still work, it is because > > sizeof(int) == sizeof(long) on the machine you are working on) > > I'm somewhat bothered that none of you are specifying which > implementations of the two languages you are discussing. When you want > to interface two different language systems, you have to figure out > how both of them map the language structures to machine code, and > figure out the right hacks to get the information across. In any > case, the particular solution will only be good for the two language > implementations involved. > > Dale > -- > Dale Worley Cullinet Software ARPA: cullvax!drw@eddie.mit.edu > UUCP: ...!seismo!harvard!mit-eddie!cullvax!drw > If you light a match, how much mass does it convert into energy? F77 on Berkley Unix OS. Its been a while since I've played with stuff like that. Some vendor's language manual with have the details of implementation. -- Eddie Wyatt e-mail: edw@ius2.cs.cmu.edu terrorist, cryptography, DES, drugs, cipher, secret, decode, NSA, CIA, NRO.
henry@utzoo.UUCP (Henry Spencer) (06/21/87)
> 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... It is worth mentioning another aspect of the VAX Calling Standard: it is Ghodawful slow. The all-singing-all-dancing CALLS and CALLG are often slower than "rolling your own" using more primitive instructions. (I am told that the insides of VMS do this quite extensively.) C function calls using CALLS on the VAX 780 are slower than C function calls on the 11/70, which is a bit embarrassing considering relative ages, technologies, and data-path widths (not to mention prices). -- "There is only one spacefaring Henry Spencer @ U of Toronto Zoology nation on Earth today, comrade." {allegra,ihnp4,decvax,pyramid}!utzoo!henry
peter@sugar.UUCP (Peter DaSilva) (06/26/87)
> Fortrash strings (I think) have the format first four(?) bytes > holds the size of the string followed by the characters in the string. That is implementation dependent. They may also do such things as store a byte length at the address, or even store a value *before* the address passed. They may not even have a length you can use at all, if it's an old Fortran. I would suggest you do this: char foo[80]; main() { int i; fortest(); for(i = 0; i < 80; i++) printf("%03o", foo[i]); } SUBROUTINE FORTEST CHARACTER*80 BAR COMMON /FOO/ BAR BAR = 'TEST STRING' END Then get your ascii table and examine the output.
ark@alice.UUCP (07/01/87)
In article <223@sugar.UUCP>, peter@sugar.UUCP writes: > That is implementation dependent. They may also do such things as store > a byte length at the address, or even store a value *before* the address > passed. They may not even have a length you can use at all, if it's an > old Fortran. It is difficult and unnecessary for a Fortran 77 compiler that conforms to the ANSI standard to store a length with a character string. It is unnecessary because the length of every string is known to the compiler as a constant, except for parameters. Parameters must be handled specially anyway, because they can be temporaries. It is difficult because the language defines the meaning of things like: CHARACTER A*10, B*10, C*20 COMMON A, B EQUIVALENCE (A, C) so that the first 10 characters of C are equivalent to the 10 characters of A and the next 10 characters of C are equivalent to the 10 characters of B. It's hard to do this and still store a count.