Iso c binding
From ScorecWiki
Contents |
[edit]
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
[edit]
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 .
[edit]
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
[edit]
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; }
[edit]
compile.sh
#!/bin/bash -x gfortran -c prog.f90 gcc -c myC_func.c gfortran prog.o myC_func.o -o main.exe