Iso c binding

From ScorecWiki

Jump to: navigation, search

Contents

Useful iso_c_binding links

Intel docs:

https://software.intel.com/en-us/node/510843

GNU docs:

http://gcc.gnu.org/onlinedocs/gfortran/Interoperable-Subroutines-and-Functions.html

http://gcc.gnu.org/onlinedocs/gfortran/Working-with-Pointers.html

A library which uses iso_c_bindings:

https://red.ices.utexas.edu/projects/software/wiki/MASA

An example of allocating a contiguous C array to Fortran as a multidimensional array:

https://github.com/SCOREC/xgc_scorec/wiki/Support-of-Fortran-array-syntax-on-memory-allocated-by-C

Example

The following example demonstrates passing a pointer to a two dimensional array from Fortran to C. Run compile.sh to build. Tested with GCC 4.4.5 .

prog.f90

          program main
            use iso_c_binding
            implicit none
            interface
              subroutine my_routine(p,r,c) bind(c,name='myC_func')
                import :: c_ptr
                import :: c_int
                type(c_ptr), value :: p
                integer(c_int), value :: r
                integer(c_int), value :: c
              end subroutine
            end interface
            real (c_double), allocatable, target :: xyz(:,:)
            real (c_double), target :: abc(7,3)
            type(c_ptr) :: cptr
            allocate(xyz(7,3))
            cptr = c_loc(xyz(1,1))
            write(*,'(a,z20)') '#fortran address:', c_loc(abc(1,1))
            xyz=-1.0
            call my_routine(cptr,7,3)
            xyz(1,1)=1.0
            xyz(2,1)=2.0
            xyz(3,1)=3.0
            call my_routine(cptr,7,3)
            deallocate(xyz)

            write(*,'(a,z20)') '#fortran address:', c_loc(abc(1,1))
            cptr = c_loc(abc(1,1))
            abc=-5.0
            call my_routine(cptr,7,3)
            abc(1,1)=11.0
            abc(2,1)=12.0
            abc(3,1)=13.0
            call my_routine(cptr,7,3)

          end program main

myC_func.c

#include <stdio.h>

void myC_func(void *p, int rows, int cols) {

  static int round = 1;

  double *dptr;
  dptr=(double *)p;
  printf("#C address: %p\n", dptr);
  int i;
  if ( 1 == round ) {
     printf("*********************************************\n");
     printf(" [<call#>] <var>[<C idx>] (<F idx>) = <value>\n");
     printf("*********************************************\n");
  }
  for (i=0; i<rows; i++)
    printf(" [%d] ptr[%3d,  0] (  1,%3d) = %f\n",round,i,i+1,dptr[i*cols]);

  for (i=0; i<cols; i++)
    printf(" [%d] ptr[  0,%3d] (%3d,  1) = %f\n",round,i,i+1,dptr[i]);

  round=round+1;
  return;
}

compile.sh


#!/bin/bash -x

 gfortran -c prog.f90 
 gcc -c myC_func.c 
 gfortran prog.o myC_func.o -o main.exe
Personal tools