leichterj@roxie.DEC (Jerry Leichter) (01/28/86)
Question: on a VMS system, can you call a C function from a fortran program? If so, how? I have written up a test program to try it out and it compiles and links cleanly but when I try to run it I get a VMS system error "access violation". Connie Falk (falk%uiucuxc@a.cs.uiuc.edu) Sure, no problem. All the standard VMS compilers use compatible calling conventions. HOWEVER, various languages have different parameter passing semantics. Let's start with simple numeric variables. C passes these by immediate value; FORTRAN by reference. That is: A C function expects to receive the actual number, while the FORTRAN function or subroutine expects to receive the AD- DRESS at which it can find the number. Thus, if you have the FORTRAN FUNCTION F(I) I = I + 1 END and you, in C, do: int z = 1; F(z); F will receive "1", which it will take as an address, and "*1" will cause an immediate access violation. The fix is simple: Since F wants an address, give it one: int z = 1; F(&z); will work fine. In fact, the VAX C compiler even allows you to apply "&" to constants IN ARGUMENT LISTS; a unique memory location will be loaded with the constant, and its address will be passed. So, you could do: F(&2); /* Useless, of course */ Going the other way, there are two options: (a) Since FORTRAN will pass, not (say) an integer but the address of one, instead of: g(x) int x; simply use: g(x) int *x; g can now be called directly from FORTRAN. (b) VAX FORTRAN includes an extension that allows you to specify that a par- ticular actual parameter is to be passed by value rather than reference. Simply do, for example: gg(%VAL(x)) to pass x to gg by value (as an int) rather than by reference (int *). You'll note that so far I've only discussed simple numeric parameters. Beyond that, things get a bit more complex. For example, 1-d arrays should work fine - though of course FORTRAN arrays are usually 1-based while C arrays are 0-based - but FORTRAN stores multi-dimensional arrays in column-major order while most other languages, C included, use row-major order (or is it the other way around)? This can be handled, though it will require some careful work. Finally, strings are a bit more complicated. C generally stores strings as NUL-terminated arrays, and passes them by passing the address of the array. FORTRAN uses descriptors to define strings; what is passed is the address of a descriptor, which in turn contains such information as the address and length of the actual string. Converting back and forth isn't hard but is too involved to go into here. There is a fair amount of discussion of all these issues in the VMS documen- tation. See in particular the VAX C manual's section on mixed language programming and the introduction to the System Services and RTL manuals. -- Jerry