alf@edstip.EDS.COM (John Hamill) (09/19/89)
I would like to know how I can combine Fortran and "c" programs.
If you know of a good book that gives examples could you send me the name.
If you have an example, could you send me it.
Thank you in advance.
--
/~~| |\ |\ John W. Hamill, EDS `""""""" UUCP: ...!uunet!edsews!edstip!alf
| | |/ |/ 1400 N. Woodward Ave (. (. > alf@edstip.EDS.COM
\__\_/^\_/|\_/ Bloomfield Hills, Voice:(313)645-4524 Fax:645-4824
\/ MI 48013 * The above are my views only!!
bam@bnlux0.bnl.gov (Bruce Martin) (09/23/89)
In article <794@edstip.EDS.COM> alf@edstip.EDS.COM (John Hamill) writes: > >I would like to know how I can combine Fortran and "c" programs. >... Two different kinds of problems are involved: langage differences & code- generator differences. Firstly, Fortran's semantics are not the same as C's. Secondly, two compilers are involved. (In your example, one is fortran and one is c. In general, it could even be 2 fortrans on the same machine.) LANGUAGE DIFFERENCES Some things in one language may not exist in the other and must either mapped or avoided. (For example, Fortran COMPLEX and CHARACTER can be mapped as C structures, but Fortran COMMON and C recursion are probably best avoided). Since C always calls by value and Fortran always calls by reference (or value/ result, if you want to be pedantic), C arguments must therefore be pointers. If you're using unix, you're in luck. "f77" was designed to be compatible with "cc. There is an excellent article by Stu Feldman, which describes how Fortran and C argument lists correspond, what extra information is added (e.g. to convey type and string-length information), how complex numbers are handled (with pointers to static structures), how string lengths are passed, why procedure parameters always require type information, and many more fascinating details. For these two compilers, a correspondence is established between C and Fortran, regardless of the hardware. For other compiler combinations, such correspondences must be established even if calling sequence conventions agree, and any restrictions must be clear. CALLING SEQUENCES Each compiler has its own code generator. They may or may not be compatible in how code is generated for calling sequences. (If they don't claim to be compatible with each other, they probably are not -- unless there is a vendor-specified calling-sequence convention that they both follow.) If conventions differ, but are fully specified for each, you may be able to write an assembly-language "wrapper" to convert the calling conventions. (One for each call is easier; a general-purpose wrapper may be more useful.) The major considerations deal with the way in which arguments are passed to the called procedure, and how it returns. How are arguments transmitted? Nowadays, most implementations use a stack. Is the same stack used? How many bytes (or whatever) are pushed for an address? (If your hardware has different kinds of addresses, like "long" & "short", do both compilers agree when to use each kind and how to represent them?) Are values ever (or always) pushed? Is auxillary information necessary? (e.g. string length, dope vectors, type information, etc.) Are the arguments pushed in left-to-right order or right-to-left order? Stacks are wonderful, but when the wrong stuff is popped for a return address, there is usually no evidence left by the time you examine the crash site. Where is the return address put? How are return values represented and where are they placed? Are there any other things sent along for the ride? In some cases, the called routine is expected to do some housekeeping, like saving a certain register, cleaning up stacks, adding something to the return address, etc., etc. These assumed conventions may be peculiar to each compiler. OTHER CONSIDERATIONS Assuming they do follow the same conventions, some issues remain to be considered. If you are merely calling a Fortran math routine which does no I/O, then you may not have to worry. However, if you expect a C routine and a Fortran routine to take turns manipulating the same file, you may find that different run-time code is linked by each language processor. In fact, it may be the main program that determines which files you can use, and I/O may be limited to one language. Exit from the program may have to be from a routine in the same language as the main program, and error aborts in the other language might cause trouble (like weird messages & unflushed buffers). Make sure that the data representation agrees. It is not unheard of to have different floating-point representation in two languages on the same machine. Math libraries of different languages may make different assumptions, even if the representation is the same. DO NOT DESPAIR I don't mean to discourage you. You may find that the manuals promise compatibility by design (and that they aren't lying too much). You may find, upon analysis, that a wrapper is pretty straightforward (like reversing the order of the arguments and maybe saving a pointer or adjusting a stack frame). If so, the extra power you will obtain will be very useful. Document you findings, write it up, put the wrapper in the library, etc. It can be well worth the effort, and pay future dividends. [I know. It was. It did!] -/s/- BAM Bruce A. Martin Grumman Aircraft Systems [Address given for identification only.] (Mailstop B02-106) [Every conceivable disclaimer applies!!] Bethpage, NY 11714 [Opinions are mine only, & will change,] (516) 577-1426 [without notice, whenever appropriate!!] P.S. Feel free to ask me about specifics. No promises, but I'll help if I can.