(j3.2006) One more thing for the C TR

Van Snyder Van.Snyder
Thu Sep 22 22:11:44 EDT 2011


It would be useful if the C TR required a header file containing the
values of the named constants in Table 15.2 in the 2008 standard, with
the names specified there, maybe in upper case.

I needed to test whether c_int == kind(0) (alternatively c_long) and
either use c_f_pointer, or use c_f_pointer and allocate and assign and
ultimately deallocate to grab an argument.  I had to trust that the C
side (actually C++ side) was compiled correctly (with the correct
command-line options to create typedefs consistent with the Fortran
side, using #ifdef etc.).  If I had been able to pass the kind as an
argument it would have been helpful.

An example abstracted from the bigger problem is attached.  Be careful
to compile either both with -DLONG or both without -DLONG.

Van

-------------- next part --------------
A non-text attachment was scrubbed...
Name: cpptest.cpp
Type: text/x-c++src
Size: 554 bytes
Desc: not available
URL: <http://j3-fortran.org/pipermail/j3/attachments/20110922/dff646ec/attachment.bin>
-------------- next part --------------
module fortmodule

  implicit none
  private

contains

  subroutine fortfun ( s ) bind(C,name='MyFortfun')

    use, intrinsic :: iso_c_binding, only: c_f_pointer, c_long, c_ptr
    type(c_ptr), intent(in), value :: s
    interface
      function strlen ( P ) bind(C)
        import ! Interface body don't have host access otherwise
        integer(c_long) strlen
        type(c_ptr), intent(in), value :: P
      end function strlen
    end interface
    integer :: i, n
    character, pointer :: c(:)
    n = strlen(s)
    call c_f_pointer ( s, c, [n] )
    write ( *, '(a)', advance='no' ) 'Now in fortfun, received "'
    do i = 1, n
      write ( *, '(a)', advance='no' ) c(i)
    end do
    write ( *, '(a)' ) '"'

  end subroutine fortfun

  subroutine AnotherFun ( c ) bind(C,name='More_Fun')

    use, intrinsic :: iso_c_binding, only: c_null_char
    character, intent(in) :: c(*)
    integer :: i
    i = 0
    write ( *, '(a)', advance='no' ) 'Now in AnotherFun, received "'
    do
      i = i + 1
      if ( c(i) == c_null_char ) exit
      write ( *, '(a)', advance='no' ) c(i)
    end do
    write ( *, '(a)' ) '"'

  end subroutine AnotherFun

  subroutine ArrayFun ( c, rank, dims ) bind(C)

#if (defined LONG)
    use, intrinsic :: iso_c_binding, only: c_f_pointer, c_int, me=>c_long, c_ptr
#else
    use, intrinsic :: iso_c_binding, only: c_f_pointer, c_int, me=>c_int, c_ptr
#endif
    type(c_ptr), intent(in), value :: C
    integer(c_int), intent(in), value :: Rank
    integer(me), intent(in) :: Dims(*)
    integer(me), pointer :: Rank1(:), Rank2(:,:) ! C_INT or C_LONG integer
    integer, pointer :: R1(:), R2(:,:) ! Default integer
    if ( me == kind(0) ) then
      print '(a)', 'In ArrayFun, same kinds'
      select case ( rank )
      case ( 1_c_int )
        call c_f_pointer ( c, rank1, dims(1:rank) )
        print '(6i3)', rank1
      case ( 2_c_int )
        call c_f_pointer ( c, rank2, dims(1:rank) )
        print '(3i3)', rank2
      end select
    else
      print '(a)', 'In ArrayFun, different kinds'
      select case ( rank )
      case ( 1_c_int )
        call c_f_pointer ( c, rank1, dims(1:rank) )
        allocate ( r1(dims(1)) )
        r1 = rank1
        print '(6i3)', r1
        deallocate ( r1 )
      case ( 2_c_int )
        call c_f_pointer ( c, rank2, dims(1:rank) )
        allocate ( r2(dims(1),dims(2)) )
        r2 = rank2
        print '(3i3)', r2
        deallocate ( r2 )
      end select
    end if

  end subroutine ArrayFun

end module fortmodule



More information about the J3 mailing list