A ForTran example shows how to call a ForTran function from rexx using a C function as an intermediary. It works with the GNU Compiler, and might work with f2c. This is unsupported.
Program is distributed as ZIP package: download to temporary directory and unpack to destination folder. See below for download link(s).
Following ones are the download links for manual installation:
Fortran functions called from Rexx - Example (15/3/2002, Patrick TJ McPhee) | Readme/What's new |
This is an example which shows how to call a ForTran function from
a Rexx program. The approach is to build a wrapper function in C which
uses the Rexx SAA API, convert the arguments into the format required
by the ForTran function, then call it. This is not meant to be
a comprehensive tutorial, just an example to help out someone who
posted to comp.lang.rexx.
This example works with the GNU compiler collection, and has been
explicitly tested using mingw gcc 2.95.2 on windows NT. The code
likely work with any gcc implementation on any 32-bit platform, and
with f2c with slight modifications (change g2c.h to f2c.h in the C
file). With other ForTran and C compilers, the calling convention
is likely to be different, so you'd need to read up on it.
I wrote a lot of ForTran code in 1986, but none since then, so bear
with me. The example program takes four arguments: aone and athree
are real numbers which in a real program would be used in
some useful way. atwo is a character string, and atl is the length
of the string. I tried defining the string as character*255, but I
got a lot of crap printed on the screen, so I took the approach
of passing the length explicitly. The function returns a real.
On the C side, the function name is the same as the ForTran function,
but with _ appended to it. Each non-character argument becomes a
pointer to a variable of the corresponding type. Character variables
are replaced by a C character string. For each character, the length
of the C buffer is passed as an extra argument at the end of the call.
Look at the difference between ffunc_ in cbase.c and ffunc in ffunc.c.
Each ForTran function has a corresponding C function which satisfies
the requirement of the SAA API. The file ffunc.def has an EXPORTS entry
for each of these functions. You need to load each function explicitly.
For an example of writing a sysloadfuncs-style function, look at the
source code from regutil.
I use the C function atof() to convert each argument to a real because
I don't know how to do the conversion in ForTran. I use sprintf to
convert the return code from the ForTran function back into a C string,
for the same reason.
If you do know how to convert character types in ForTran, it's probably
better to do all the conversion in the ForTran function itself (since
your goal in writing in ForTran is to minimize the amount of C you
write in your lifetime). In that case, your function should also return
a character type, and the prototype you use on the C side should be
something like:
void ffunc_(char * result, int resultlen, <other arguments, as above>);
resultlen should be 255 for a normal SAA implementation.
Other caveats:
- if you convert the variable in the C functions and you aren't using
Regina, you probably need to copy the character string into a buffer
and null-terminate it before calling atof();
- The function to convert into an integer is atoi().
- If you are using a 64-bit platform (DEC alpha, and possibly HP-UX,
AIX, Solaris with the appropriate compiler flags), the RXSTRING
strlength variable is probably not the same size as the ForTran
integer variable, so you'll need to do something like
integer a2l;
a2l = argv[1].strlength;
ffunc_(..., &a2l, ...);
- & before the variable means to pass it by reference.
Good luck,
patrick tj mcphee
ptjm@interlog.com
|
hobbes.nmsu.edu/download/pub/os2/dev/rexx/fortranexample.zip | local copy |
This work is licensed under a Creative Commons Attribution 4.0 International License.
Add new comment