Of course, exchanging pointers to dynamic memory between C and FORTRAN is only part of the story. We must also be able to access the memory from both languages.
When importing a FORTRAN pointer into C, the first step is to use cnfCptr to convert it to a C pointer of type void*. You can then use a cast to convert to the appropriate C pointer type (which you must know in advance) in order to access the values stored in the memory. For example, to print out the contents of a dynamically allocated array of FORTRAN REAL data from a C function, you might use the following:
F77_SUBROUTINE(rprint)( INTEGER(N), POINTER(FPNTR) ) { GENPTR_INTEGER(N) GENPTR_POINTER(FPNTR) F77_REAL_TYPE *cpntr; /* Convert to a C pointer of the required type. */ cpntr=(F77_REAL_TYPE)cnfCptr(*FPNTR); /* Access the data. */ for(i=0;i<*N;i++) printf("%g\n",cpntr[i]); }
Accessing dynamically allocated memory via a pointer from FORTRAN
requires two steps. First, the pointer value stored in a
FORTRAN INTEGER must be expanded to its full value (if
necessary), equivalent to the full equivalent C pointer. This value
must then be turned into a FORTRAN array which can be accessed. This
requires that the pointer be passed to a separate FORTRAN routine
using the %VAL facility.1 For example, to convert a pointer into a REAL
array, you might call an auxiliary routine RWRITE as
follows:
INCLUDE 'CNF_PAR' ... CALL RWRITE(N,%VAL(CNF_PVAL(PNTR)))and the RWRITE routine could then access the array of values as follows:
SUBROUTINE RWRITE( N, RDATA ) INTEGER I, N REAL RDATA( N ) DO 1 I = 1, N WRITE(*,*) RDATA(I) 1 CONTINUE END
Note how the argument of the %VAL directive is CNF_PVAL(PNTR). The FORTRAN-callable CNF_PVAL function serves to expand the pointer value out to its full length (equivalent to calling cnfCptr from C). The data type returned by this function will depend on the length of C pointers on the machine being used and may not be a standard FORTRAN type (for instance, on DEC Alphas it is an INTEGER*8 function). However, the data type declaration for this function is encapsulated in the CNF_PAR include file, so you need not include non-standard type declarations directly in your own software.
Historical note. Much existing Starlink software does not use the CNF_PVAL function because it was written before the need to operate on 64-bit operating systems arose. Omitting this function, and passing a FORTRAN pointer directly to %VAL, will not cause problems on systems where C pointers and FORTRAN INTEGERs are the same length (or where linker options can be used to make them appear so). However, its use is recommended for new software in order to protect against possible future operating system developments.
CNF and F77 Mixed Language Programming -- FORTRAN and C