Can a scalar function C be called from Fortran with array arguments?

Recently, I came across a situation where I wanted to call a C function from Fortran due to a useful piece of C code. For the convenience of operations with arrays, I wanted to be able to call this function also with array arguments, but it took only scalar arguments.

In Fortran, you can, of course, simply declare an elemental procedure to achieve this, and you can declare an interface for a C procedure with bind(C) . However, since C does not have the concept of elementary procedures, the Fortran (2008) standard excludes this combination:

C1246 An elementary procedure must not have a BIND attribute.

So, can this functionality be achieved in Fortran?

+4
source share
1 answer

After some searching, I found that this is possible and quite simple using Fortran 2003 and the iso_c_binding built-in module; I thought I should document this here. The interface with the bind attribute can still be pure , so it can be found in the Fortran procedure, which itself is elemental .

The following is a brief example with the C99 isnan macro, which returns a nonzero integer value if its argument is NaN. Of course, this can also be done for any custom C / C ++ function that is free from side effects.

 elemental function isnan(val) use, intrinsic :: iso_c_binding implicit none real(c_double), intent(in) :: val logical(c_bool) :: isnan interface pure function isnan_C(val) bind(C, name = 'isnan') import ! Pass the parameter by value: real(c_double), value, intent(in) :: val integer(c_int) :: isnan_C end function end interface isnan = isnan_C(val) /= 0_c_int end function 

Example output using an array with some NaN values:

 program main use, intrinsic :: iso_c_binding implicit none real(c_double) :: nan(2,2) = 0. nan(:,2) = nan(1,1)/0. write(*,'(4F6.2 / 4L6)') nan, isnan(nan) ! Output: 0.00 0.00 NaN NaN ! FFTT end program 
+7
source

All Articles