module wrapper use iso_c_binding implicit none interface pure function strlen(s) result(result) bind(C) import c_ptr, c_size_t integer(c_size_t) :: result type(c_ptr), value, intent(in) :: s end function strlen end interface contains subroutine c_f_string_ptr(c_str, f_str) type(c_ptr), intent(in) :: c_str character(len=*), intent(out) :: f_str character(len=1,kind=c_char), dimension(:), pointer :: p integer :: i if (.not. c_associated(c_str)) then f_str = ' ' else call c_f_pointer(c_str, p, [huge(0)]) i=1 do while(p(i)/=C_NULL_CHAR .and. i<=len(f_str)) f_str(i:i) = p(i) i = i+1 end do if (i < len(f_str)) f_str(i:) = ' ' end if end subroutine c_f_string_ptr pure logical function c_associated_pure(ptr) result(associated) type(c_ptr), intent(in) :: ptr integer(c_intptr_t) :: iptr iptr = transfer(ptr,iptr) associated = (iptr /= 0) end function c_associated_pure pure function c_strlen_safe(s) result(length) integer(c_size_t) :: length type(c_ptr), value, intent(in) :: s if (.not. c_associated_pure(s)) then length = 0 else length = strlen(s) end if end function c_strlen_safe function c_f_string_or_null(cptr) result(fptr) type(c_ptr), intent(in) :: cptr character(len=c_strlen_safe(cptr)), pointer :: fptr if (.not. c_associated(cptr)) then nullify(fptr) else allocate(fptr) call c_f_string_ptr(cptr, fptr) end if end function c_f_string_or_null function c_f_string(cptr) result (fstr) type(c_ptr), intent(in) :: cptr character(len=c_strlen_safe(cptr)) :: fstr if (.not. c_associated(cptr)) then fstr = ' ' else call c_f_string_ptr(cptr, fstr) end if end function c_f_string subroutine c_func(a, b, c) BIND(C) integer(c_int), intent(in) :: a type(c_ptr), intent(in) :: b type(c_ptr), intent(in) :: c character(len=C_strlen_safe(b)), pointer :: bf character(len=C_strlen_safe(c)), pointer :: cf bf => c_f_string_or_null(b) cf => c_f_string_or_null(c) call func(a, bf, cf) if (associated(bf)) deallocate(bf) if (associated(cf)) deallocate(cf) end subroutine c_func subroutine cc_func(a, b, c) BIND(C) integer(c_int), value, intent(in) :: a type(c_ptr), value, intent(in) :: b type(c_ptr), value, intent(in) :: c call func(a, c_f_string(b), c_f_string(c)) end subroutine cc_func subroutine func(a, b, c) integer, intent(in), optional :: a character(*), intent(in), optional :: b character(*), intent(in), optional :: c if (present(a)) then print *, 'a=', a end if if (present(b)) then print *, 'b=', b end if if (present(c)) then print *, 'c=', c end if end subroutine func end module wrapper