Questions tagged [fortran-iso-c-binding]

The standard Fortran interoperability with C consists of the BIND(C) attribute, which enables C calling conventions and changes symbol names and the ISO_C_BINDING module , which provides access to named constants that represent kind type parameters of data representations compatible with C types, the derived type C_PTR corresponding to any C data pointer type, the derived type C_FUNPTR corresponding to any C function pointer type, and four procedures.

  1. Introduction
    Fortran 2003 provides a standardized mechanism for interoperating with C. This support is widely available in Fortran 95 compilers that partially implement Fortran 2003. This support covers:

    • interoperability of procedures - a means of referencing procedures that are defined in the C programming language, or that can be represented by C language prototypes, and a means of specifying that a procedure defined in Fortran can be called from C;

    • interoperability of types - a means of declaring types and enumerations in Fortran that correspond to C types;

    • interoperability of global data objects - a means of declaring global variables that are associated with C variables with external linkage;

    • an intrinsic module (ISO_C_BINDING) that provides access to named constants and procedures relevant to C interoperability.

Clearly, any interoperable entity must be such that equivalent declarations of it may be made in the two languages. This is enforced within the Fortran program by requiring all such entities to be interoperable. We will explain in turn what this requires for types, variables, and procedures. We finish with two examples.

  1. Interoperability of intrinsic types
    There is an intrinsic module called ISO_C_BINDING that contains named constants holding kind type parameter values for intrinsic types. Their names are shown in Table 1, together with the corresponding C types. The processor is not required to support all of them. Lack of support is indicated with a negative value.

    Table 1. Interoperability between Fortran and C types

    Type        Named constant        C type or types
    INTEGER     C_INT                 int, signed int
                C_SHORT               short int, signed short int
                C_LONG                long int, signed long int
                C_LONG_LONG           long long int, signed long long int
                C_SIGNED_CHAR         signed char, unsigned char
                C_SIZE_T              size_t
                C_INT_LEAST8_T        int_least8_t
                C_INT_LEAST16_T       int_least16_t
                C_INT_LEAST32_T       int_least32_t
                C_INT_LEAST64_T       int_least64_t
                C_INT_FAST8_T         int_fast8_t
                C_INT_FAST16_T        int_fast16_t
                C_INT_FAST32_T        int_fast32_t
                C_INT_FAST64_T        int_fast64_t
                C_INTMAX_T            c intmax_t
    REAL        C_FLOAT               float, float _Imaginary
                C_DOUBLE              double, double _Imaginary
    COMPLEX     C_LONG_DOUBLE         long double, long double _Imaginary
                C_COMPLEX             _Complex
                C_DOUBLE_COMPLEX      double _Complex
                C_LONG_DOUBLE_COMPLEX long double _Complex
    LOGICAL     C_BOOL                _Bool
    CHARACTER   C_CHAR                char  
    

    For character, interoperability also requires that the length type parameter be omitted or be specified by an initialization expression whose value is one. The following named constants (with the obvious meanings) are provided: C_NULL_CHAR, C_ALERT, C_BACKSPACE, C_FORM_FEED, C_NEW_LINE, C_CARRIAGE_RETURN, C_HORIZONTAL_TAB, C_VERTICAL_TAB.

  2. Interoperability with C pointers
    For interoperating with C pointers (which are just addresses), the module contains a derived type C_PTR that is interoperable with any C pointer type and a named constant C_NULL_PTR with the value NULL of C.
    The module also contains the following procedures:

    • C_LOC (X) is an inquiry function that returns the C address of X.
      X is permitted to be a procedure that is interoperable (see para. 5) or a variable that has the TARGET attribute and is either interoperable or is an allocated allocatable variable that has interoperable type and type parameters.
    • C_ASSOCIATED (C_PTR1[, C_PTR2]) is an inquiry function that returns a default logical scalar. It has the value false if C_PTR1 is a C null pointer or if C_PTR2 is present with a different value; otherwise, it has the value true.
    • C_F_POINTER (CPTR, FPTR [, SHAPE]) is a subroutine with arguments CPTR is a scalar of type C_PTR with intent IN. Its value is the C address of an entity that is is interoperable with variables of the type and type parameters of FPTR. It shall not be the C address of a Fortran variable that does not have the TARGET attribute. FPTR is a pointer that becomes pointer associated with the target of CPTR. If it is an array, its shape is specified by SHAPE.
      SHAPE (optional) is a rank-one array of type integer with intent IN. If present, its size is equal to the rank of FPTR. If FPTR is an array, it must be present.

    This is the mechanism for passing dynamic arrays between the languages. A Fortran pointer or assumed-shape array cannot be passed to C since its elements need not be contiguous in memory. However, an allocated allocatable array may be passed to C and an array allocated in C may be associated with a Fortran pointer.

  3. Interoperability of derived types
    For a derived type to be interoperable, it must be given the BIND attribute explicitly:

    TYPE, BIND(C) :: MYTYPE
        :
    END TYPE MYTYPE
    

    Each component must have interoperable type and type parameters, must not be a pointer, and must not be allocatable. This allows Fortran and C types to correspond, for example:

    typedef struct {
        int m, n;
        float r;
    } myctype
    

    is interoperable with

    USE ISO_C_BINDING
    TYPE, BIND(C) :: MYFTYPE
        INTEGER(C_INT) :: I, J
        REAL(C_FLOAT) :: S
    END TYPE MYFTYPE
    

    The name of the type and the names of the components are not significant for interoperability.

    No Fortran type is interoperable with a C union type, struct type that contains a bit field, or struct type that contains a flexible array member.

  4. Interoperability of variables
    A scalar Fortran variable is interoperable if it is of interoperable type and type parameters, and is neither a pointer nor allocatable.

    An array Fortran variable is interoperable if it is of interoperable type and type parameters, and is of explicit shape or assumed size. It interoperates with a C array of the same type types parameters and shape, but with reversal of subscripts. For example, a Fortran array declared as:

    INTEGER :: A(18, 3:7, *)
    

    is interoperable with a C array declared as

    int b[][5][18]  
    
  5. Interoperability of procedures A Fortran procedure is interoperable if it has an explicit interface and is declared with the BIND attribute:

    FUNCTION FUNC(I, J, K, L, M) BIND(C)
    

    All the dummy arguments must be interoperable. For a function, the result must be scalar and interoperable. The procedure has a 'binding label', which has global scope and is the name by which it is known to the C processor. By default, it is the lower-case version of the Fortran name. For example, the above function has the binding label func. Another binding label may be specied:

    FUNCTION FUNC(I, J, K, L, M) BIND(C, NAME='C_Func')
    

    Such a procedure corresponds to a C function prototype with the same binding label. For a function, the result must be interoperable. For a subroutine, the prototype must have a void result.

  6. Interoperability of global data An interoperable module variable or a common block with interoperable members may be given the BIND attribute:

    USE ISO_C_BINDING
        INTEGER(C_INT), BIND(C) :: C_EXTERN
        INTEGER(C_LONG) :: C2
        BIND(C, NAME='myVariable') :: C2
        COMMON /COM/ R, S
        REAL(C_FLOAT) :: R, S
        BIND(C) :: /COM/
    

    It has a binding label defined by the same rules as for procedures and interoperate with a C variable of a corresponding struct type.

  7. Example of Fortran calling C C Function Prototype:

    int C_Library_Function(void* sendbuf, int sendcount, int *recvcounts)
    

    Fortran Module:

    MODULE FTN_C
        INTERFACE
            INTEGER (C_INT) FUNCTION C_LIBRARY_FUNCTION  &
                (SENDBUF, SENDCOUNT, RECVCOUNTS)         &
                BIND(C, NAME='C_Library_Function')
                USE ISO_C_BINDING
                IMPLICIT NONE
                TYPE (C_PTR), VALUE :: SENDBUF
                INTEGER (C_INT), VALUE :: SENDCOUNT
                TYPE (C_PTR), VALUE :: RECVCOUNTS
            END FUNCTION C_LIBRARY_FUNCTION
        END INTERFACE
    END MODULE FTN_C
    

    Fortran Calling Sequence:

    USE ISO_C_BINDING, ONLY: C_INT, C_FLOAT, C_LOC
    USE FTN_C
    ...
    REAL (C_FLOAT), TARGET :: SEND(100)
    INTEGER (C_INT)        :: SENDCOUNT
    INTEGER (C_INT), ALLOCATABLE, TARGET :: RECVCOUNTS(:)
    ...
    ALLOCATE( RECVCOUNTS(100) )
    ...
    CALL C_LIBRARY_FUNCTION(C_LOC(SEND), SENDCOUNT,     &
    C_LOC(RECVCOUNTS))
    ...
    
  8. Example of C calling Fortran
    Fortran Code:
    SUBROUTINE SIMULATION(ALPHA, BETA, GAMMA, DELTA, ARRAYS) BIND(C)
        USE ISO_C_BINDING
        IMPLICIT NONE
        INTEGER (C_LONG), VALUE                 :: ALPHA
        REAL (C_DOUBLE), INTENT(INOUT)          :: BETA
        INTEGER (C_LONG), INTENT(OUT)           :: GAMMA
        REAL (C_DOUBLE),DIMENSION(*),INTENT(IN) :: DELTA
        TYPE, BIND(C) :: PASS
            INTEGER (C_INT) :: LENC, LENF
            TYPE (C_PTR)    :: C, F
        END TYPE PASS
        TYPE (PASS), INTENT(INOUT) :: ARRAYS
        REAL (C_FLOAT), ALLOCATABLE, TARGET, SAVE :: ETA(:)
        REAL (C_FLOAT), POINTER :: C_ARRAY(:)
        ...
        ! Associate C_ARRAY with an array allocated in C
        CALL C_F_POINTER (ARRAYS%C, C_ARRAY, (/ARRAYS%LENC/) )
        ...
        ! Allocate an array and make it available in C
        ARRAYS%LENF = 100
        ALLOCATE (ETA(ARRAYS%LENF))
        ARRAYS%F = C_LOC(ETA)
        ...
    END SUBROUTINE SIMULATION
    
    C Struct Declaration:
    struct pass {int lenc, lenf; float* f, *c}
    
    C Function Prototype:
    void simulation(long alpha, double *beta, long *gamma, double delta[], 
                    struct pass *arrays)
    
    C Calling Sequence:
    simulation(alpha, &beta, &gamma, delta, &arrays);
    
262 questions
22
votes
1 answer

Fortran - Cython Workflow

I would like to set up a workflow to reach fortran routines from Python using Cython on a Windows Machine after some searching I found : http://www.fortran90.org/src/best-practices.html#interfacing-with-c and…
martburg
  • 490
  • 3
  • 12
20
votes
3 answers

Sleep in Fortran

Does anyone know of an way to sleep for a given number of milliseconds in Fortran? I do not want to use non-portable system calls so anything intrinsic to Fortran or C libraries would be preferred.
Brian Triplett
  • 3,462
  • 6
  • 35
  • 61
18
votes
3 answers

Calling a FORTRAN subroutine from C

I am trying to call a FORTRAN function from C My questions are: If fortRoutine is the name of my fortran subroutine, then I am calling this from C as fortRoutine_. If fortRoutine contains only one character array argument, then can I pass like…
Kittu
  • 315
  • 1
  • 6
  • 14
15
votes
3 answers

call functions from a shared fortran library in python

I would like to call some functions from a Fortran shared library in Python. I have found some links on the net and read them, and according what I found, I should do libadd = cdll.LoadLibrary('./libbin.so') to load the shared object. However,…
Umut Tabak
  • 1,862
  • 4
  • 26
  • 41
15
votes
2 answers

Calling C function/subroutine in Fortran code

I am attempting to compile and link a Fortran code calling c subroutine: Fortran code: program adder integer a,b a=1 b=2 call addnums(a,b) stop end program C code: void addnums( int* a, int* b ) { int c = (*a) + (*b); /* convert pointers…
momba
  • 185
  • 1
  • 2
  • 8
12
votes
1 answer

Arrays of strings in Fortran-C bridges using iso_c_binding

I'm writing code that will call a C function from Fortran using Fortran's C interoperability mechanism (introduced in Fortran 2003 and implemented in newer versions of gfortran and ifort). This answer is almost what I need, but I can't quite get my…
JoeZuntz
  • 1,092
  • 10
  • 16
11
votes
7 answers

Creating a FORTRAN interface to a C function that returns a char*

I've been held up on this for about a week, now, and have searched forum after forum for a clear explanation of how to send a char* from C to FORTRAN. To make the matter more frustrating, sending a char* argument from FORTRAN to C was…
Mike Sadler
  • 1,750
  • 1
  • 20
  • 37
10
votes
2 answers

Calling Fortran subroutines with optional arguments from C++

How would I reference a Fortran function in a C++ header that uses optional arguments? Would I have a prototype in the header for each possible combination of calls? Or is this even possible? For instance, Fortran: subroutine foo(a, b, c) bind(c) …
DavidH
  • 415
  • 4
  • 21
9
votes
1 answer

Fortran intrinsic keyword in module use statement

What does it mean when the intrinsic keyword is added to the use statement for a module, as in the following example? use, intrinsic :: iso_c_binding (From 7.1 Overview of Fortran interface, FFTW 3.3.6-pl1) Does it specify that a module of that…
norio
  • 3,652
  • 3
  • 25
  • 33
8
votes
2 answers

Automatic generation of Fortran 2003 bindings from C library headers (using iso_c_bindings intrinsic module)

Is there a tool to automatically generate Fortan bindings from C library header, using intrinsic iso_c_bindings module from Fortran 2003 standard? I am not interested in translating C to Fortran, but only generating bindings.
Jakub Narębski
  • 309,089
  • 65
  • 217
  • 230
8
votes
1 answer

Assigning a Fortran integer value to a malloc-allocated C memory target

Suppose you had created a Fortran array(:) of pointers to memory allocated in C by malloc (as shown in best answer, code repeated below). Is there a way to write an integer value into this allocated memory by using the Fortran array, i.e. the…
BastH
  • 83
  • 4
8
votes
2 answers

Pass arrays from C/C++ to Fortran and return a calculated array

I am trying to pass an array from C/C++ into a Fortran 2003 module and get the calculated values back into C/C++. I've been able to pass and return single values (scalars) just fine, but getting an array back and forth is proving difficult. I've…
Adam A.
  • 320
  • 3
  • 10
8
votes
2 answers

Why ISO_C_BINDING

I am working on some fortran-calling-C code and am unclear about the use of the iso_c_binding module. I have fortran and C interfaces working successfully without iso_c_binding, and the question is if I should still explicitly bind functions and…
Korizon
  • 3,677
  • 7
  • 37
  • 52
8
votes
2 answers

C equivalent to Fortran namelist

I am used to Fortran in which I used the namelist sequential read in to get variables out of a file. This allows me to have a file which looks like this &inputDataList n = 1000.0 ! This is the first variable m = 1e3 ! Second l = -2 ! Last…
DaPhil
  • 1,509
  • 4
  • 25
  • 47
8
votes
2 answers

sockets programming gfortran

I want to be able to call networking functions in my Fortran application. My boss wants me to do everything in Fortran instead of using C and Fortran. We have already done a version of the application using PGI's Fortran compiler on Windows. We are…
hw12
  • 83
  • 1
  • 4
1
2 3
17 18