- ←Prev
- NDF
Routines for Accessing the
Extensible N-Dimensional Data Format - Next→
- TOC ↑
E THE NDF_ LIBRARY C INTERFACE
E.1 Conventions Used in the C Interface
As of Version 2.0, the NDF_ library is implemented in C, with an additional layer providing the
traditional Fortran interface described in the rest of this manual. This appendix describes the
underlying C interface, which allows NDF functions to be called from programs written in C (see
Appendix F for a list of the C functions available). It is quite easy to translate the Fortran descriptions
and examples given in the rest of this manual into C once you are aware of the conventions used. The
following notes are intended to assist with this:
-
(1)
- C function names are derived from the corresponding Fortran routine names by removing
the underscore, converting to lower case and then capitalising the fourth character. Thus,
the Fortran routine NDF_ABCDEF becomes the C function ndfAbcdef.
-
(2)
- A single header file “ndf.h” is provided to define the C interface. This contains function
prototypes together with C equivalent definitions for all the symbolic constants and error
codes used by the Fortran version. All the constants use exactly the same names (in
upper case) as in Fortran. It is recommended that you always include this file, since some
functions may be implemented via C macros and will therefore only be available in this
way.
-
(3)
- The data types used in Fortran and C for routine arguments and returned values are
related as follows:
|
|
Fortran Type | C Type |
|
|
|
|
DOUBLE PRECISION | double |
REAL | float |
INTEGER | int |
LOGICAL | int |
CHARACTER | char |
|
|
|
Note that the C interface uses “int” for both the Fortran INTEGER and LOGICAL data types, but
interprets the latter according to whether the C integer is non-zero or zero (corresponding with
Fortran’s .TRUE. and .FALSE. respectively).
-
(4)
- Input scalar arguments are always passed in C by value.
-
(5)
- Non-scalar input arguments (typically strings) are passed in C by pointer, qualified by “const” as
appropriate.
-
(6)
- All output arguments are passed in C by pointer. In the case of output array arguments, the
caller must ensure that adequate space has been allocated to receive the returned values (also see
the notes on passing character strings below). The C array notation “[ ]” is used in the
function prototypes to indicate where a returned value is an array rather than a scalar
value.
-
(7)
- All C strings should be null-terminated.
-
(8)
- Whenever a C string value is to be returned (via a argument “arg”, say, with type
char ),
the argument is followed in C by an associated integer length argument (“arg_length”)
which does not appear in the Fortran version of the routine. This additional argument
specifies the length of the character array allocated to receive the string, including
the final null. Truncation of the returned string will occur if this length would be
exceeded.
-
(9)
- An array of character strings is passed in C as an array of pointers to null-terminated strings
(like the standard argument vector passed to the C “main” function).
-
(10)
- A few functions pass HDS locators. These are stored in variables of type
HDSLoc
.
The calling function should include the hds.h
header file.
-
(11)
- Strings which are used to describe the data type of NDF components must contain the same text
in C as in Fortran. Hence, you should continue to use “_REAL”, for example, (and not
“_FLOAT”) when specifying the data type of a new NDF.
-
(12)
- When mapping NDF array components, the C interface will usually return a pointer to void,
reflecting the fact that the data type is determined at run time and is therefore not known to the
mapping function. To access the mapped data, you should cast this pointer to the appropriate
pointer type before use, as follows:
|
|
Mapped Data Type | C Pointer Cast |
|
|
|
|
_DOUBLE | (double ) |
_REAL | (float ) |
_INTEGER | (int ) |
_WORD | (short ) |
_UWORD | (unsigned short ) |
_BYTE | (signed char ) |
_UBYTE | (unsigned char ) |
|
|
|
-
(13)
- Remember that the data storage order used when mapping multi-dimensional array data
follows the Fortran convention (where the first array index varies most rapidly) and not the C
convention (where the final array index varies most rapidly).
-
(14)
- Several functions pass pointers to Objects defined by the AST library (SUN/211) for handling
world coordinate system information. These use the same C argument passing conventions for
these pointers as used in the AST library itself.
E.2 Multi-threaded Applications
In a multi-threaded context, each base NDF is either ”locked” by a specific thread, or ”unlocked”.
Locking is a long term contract that persists between invocations of public NDF functions, and can be
changed only by the caller using one of the public lock-management methods: ndfLock, ndfUnlock
and ndfLocked.
A locking contract means that:
- only the thread with the lock can invokes public NDF functions that read, write or modify
the base NDF through any identifier.
- if a thread attempts to invoke a public NDF function to read, write or modify an NDF
which it has not locked, an error is reported. The only exception is that ndfLock can be
called on an NDF that is not locked by any thread (i.e. the identifier passed to ndfLock
has been unlocked previously using ndfUnlock).
Upon creation, an NDF is always locked by the current thread. The locker thread
can at any time unlock the NDF by calling ndfUnlock on any identifier for the
NDF,
allowing another thread subsequently to lock the NDF by calling ndfLock on the same identifier. An
error is reported if the NDF is currently locked by a different thread. Calling ndfUnlock will unlock
both the supplied identifier and the associated base NDF - an error is reported if the NDF is currently
locked by another thread.
A consequence of this is that an NDF identifier will become unsable if another identifier for the same
base NDF is unlocked. However, the identifier will become usable again if the original thread regains
the lock on the NDF.
When an NDF identifier is unlocked, its associated context level is set to a special value indicating it is
not in any context. All other identifiers for the same base NDF are left unchanged. When an NDF
identifier is locked, its associated context level is set to the current context level in the thread that locks
it. The ndfEnd function only annuls NDF identifiers for base NDFs that are locked by the
current thread. The function ndfReport will report the lock state of all currently active NDF
identifiers.
E.3 C-only Functions
This section contains descriptions of functions that are only available in the C interface.
-
←Prev
- NDF
Routines for Accessing the
Extensible N-Dimensional Data Format - Next→
- TOC ↑