Calling the I/O API From C

There are a set of C-callable wrappers and/or native-C implementations for all of the public I/O API and most of the utility routines. ANSI-style function prototypes for these routines can be found in the include-file "iodecl3.h". There are four relevant archive libraries (".a" files) of compiled object files for your use. Since most of these C-callable routines are wrappers around Fortran routines which then use the Fortran run-time libraries, you need to use the relevant Fortran compiler (f90?) to do the final linking/loading step:
    cc  -c foo.c ...          # produces foo.o, etc.
    f90 -o foo foo.o ... -lm3io -lnetcdf

Generally, the public I/O API routines are int functions which return <nonzero> (generally 1) for success and 0 for failure; utility routines are more varied. Names are generally of the form *c(), so that they won't be confused with Fortran routines; a few routines— generally those named in ALLCAPS—have one single implementation directly callable from both languages.

One issue that comes up is the relationship between C strings and Fortran strings. For the most part, the wrappers take care of this for you; the notable exception is when dealing with file descriptions. Fortran strings in the file description data structures have an allocated-length field and a contents field; the contents field is padded on the right with blanks up to the allocated size (and string-comparison and assignment "do the right thing" while preventing buffer overflow). C strings are pointers to string-contents terminated by the ASCII zero (NULL character. C programmers needing to deal with these data structures should use fstr2cstr(), name2cstr(), and cstr2fstr() to convert back and forth between these two string types.

Another particular point which may come up is the relationship between Fortran REAL and C types. Under most conditions, these are the same; however, on Cray T3D and T3E platforms, Fortran REAL is C double. This is also true when the Fortran source is compiled with a -r8 flag (for those compilers which support it). The C include-file parms3.h defines type FREAL appropriately for these cases (you can activate it by the flag -DREAL8 for the custom -r8 compiles). C wrappers (e.g., interp3c(), ddtvar3c, or sortirc()) expect variables of type FREAL rather than necessarily variables of C type float.

Since calling Fortran from C or vice versa is machine-specific, the wrappers tend to have conditionally-compiled code appropriate for various architectures. It should be easy to extend the list of supported architectures to IBM AIX, HP HPUX, and Data General DG/UX by adding the appropriate symbols to the "#ifdef" in "iodecl3.h" and at the beginning of the wrappers (since all these machines still use Feldman-f77-style string passing conventions the biggest obstacle to mixed C-Fortran programming); the difficulty lies in getting hold of the manuals and finding out what symbol to use for each. The list of currently supported architectures is given below:

The list of the public C-callable I/O API routines is:

check3c() — is <timestep> available for <variable> from <file>
close3c() — close <file>
currstepc3c() — truncate <jdate,jtime> to an exact time step in the time step sequence defined by <sdate,stime,tstep>
daymonc() — find month and day-of-month for <jdate>
ddtvar3c() — compute time derivative of <variable> from <file>
desc3c() — get description for <file>
dscgridc(): get description of <named grid>
dt2strc(): Construct string "HH:MM:SS Month DD, YYYY" for <jdate-&-time>
filchk3c(): check a file for consistency with user-supplied set of file type and dimensions
find1c(), find2c(), find3c(), find4c(), findr1c(), findr2c(), findr3c(), findr4c()— find INTEGER or FREAL <key-tuple> in sorted <keytuple-table>
getdfilec() — open direct access Fortran file with specified <logical name> and <record length>, <formatting> and <read-write status>
getefilec() — open sequential Fortran file with specified <logical name> <formatting> and <read-write status>
hhmmssc() — construct string "HH:MM:SS" for <time>
init3c() — start up I/O API; return log-file unit
inqatt3c(): Inquire the names, types, and sizes of netCDF attributes for <variable> in <file>.
interp3c() — interpolate <variable> from <file> to <time>
julianc() — find Julian day number (1...365,366) for <month> <day> <year>
locat1c(), locat2c(), locat3c(), locat4c(), locatr1c(), locatr2c(), locatr3c(), locatr4c()— find insertion-point for INTEGER or FREAL <key-tuple> into sorted <keytuple-table>, or -1 if the key is already present
m3errc() <warning or error message>; with SHUT3() and EXIT(2) if fatal error;
deprecated: superseded by m3exitc() and m3warnc()
m3exitc() <exit message> with <date and time>, SHUT3() and EXIT(<status>)
m3mesgc() and m3msg2c() — Write 1-line <message> to Fortran-program log (and stdout as well, for m3msg2c().
m3warnc() <warning message> with <date and time>
mmddyyc() — construct string "Month DD, YYYY" for <jdate>
nextimec() — update <jdate-&-time> by <timestep>
open3c() — open <file> for <status>
rdatt3c(): Read value of <attribute> of <variable> in <file>.
read3c() — read <timestep> of <layer> of <variable> from <file>
read4dc() — read <timestep sequence > of <layer> of <variable> from <file>
sec2timec() — get I/O API HHMMSS time representation for <seconds>
secsdiffc() — find time difference (seconds) between two I/O API <jdate-&-time> pairs
sec2timec() — shut down I/O API; flush files to disk
sorti1c(), sorti2c(), sorti3c(), sorti4c(), sortr1c(), sortr2c(), sortr3c(), sortr4c()— sort <index table> acording to a <keytuple-table> of INTEGERs or REALs.
sync3c(): Synchronize <file> with disk: flush output; re-read header from disk.
("Volatile" files auto-synch themselves...)
time2secc() — get number of seconds for <time> given in I/O API HHMMSS time representation.
wkdayc() — get day-of-week (1...7) for <jdate> given in I/O API YYYYDDD Julian-date representation.
wratt3c(): write value of <attribute> for <variable> in <file>.
write3c() — write <timestep> of <variable> to <file>
write4dcc() — write <timestep sequence> of <variable> to <file>
xtract3c() — read <window> of <timestep> of <variable> from <file>

The list of (easily) C-callable date-and-time routines is:

currstepc() — find start of <timestep> containing <time>
daymonc() — find month and day-of-month for <jdate>
dt2strc() — Construct string for <jdate> and <time>
getdttimec() — get current wall-clock date and time
hhmmssc() — construct string "HHMMSS" for <time>
julianc() — find Julian day number (1,...,365,366) for <month> <day> <year>
mmddyyc() — construct string "Month DD, YYYY" for <jdate>
nextimec() — update <jdate>:<time> by <timestep>
sec2timec() — get Models-3 time representation for <seconds>
secsdiffc() — find time difference (seconds) between two <jdate-&-time>s
time2secc() — get number of seconds for <time>

The list of (easily) C-callable utility routines is:

dscoordc() — get description for <coordinate system>
dscgridc() — get description for <grid>
envdblec(): — get double value of logical name from the environment
envintc(): get int value of logical name from the environment
envrealc: — get float value of logical name from the environment
envstrc(): — get char * value of logical name from the environment
envync(): — get logical (int) value of logical name from the environment
find1c(), find2c(), find3c(), find4c(): find integer key-tuple in sorted keytuple-table
GCD() — greatest common divisor function
getdfilec() — Open file as Fortran direct access file with specified logical name
getefilec() — Open file as Fortran sequential file with specified logical name
m3errc() — warning message; or error message with SHUT3() and EXIT( 2 ); superseded by m3exitc() and m3warnc().
m3exitc() — exit message with SHUT3() and exit( <status> )
m3mesgc(): — Write 1-line message to Fortran-program log.
m3warnc(): — Write <warning message> with <date and time> to Fortran-program log.
POLY() degree-d polynomial interpolation function
SORTI1(), SORTI2(), SORTI3(), SORTI4(): sort <index table> acording to a <keytuple-table>

Previous Section: Calling from Fortran

Next Section: Variables and Layers and Time Steps

Up: Conventions

To: Models-3/EDSS I/O API: The Help Pages