Quantcast
Channel: Intel® Software - Intel® Fortran Compiler for Linux* and macOS*
Viewing all articles
Browse latest Browse all 2746

Interop C and Fortran problem

$
0
0

I cannot figure out, why I am not able to pass len argument correctly into c function from fortran (gfortran + gcc handle this code without any obvious problem)

simple C function

#include <stdint.h>
#include <stddef.h>
#include <stdio.h>

int32_t test (char* key, size_t len)
{
  int32_t hash = 666;
  printf("c key %s\n", key);
  printf("c len %u\n", len); // expected 2
  printf("c hash = %u\n", hash);
  return hash;
}

Fortran program

!-----------------------------------------------------------------------
!Module interface_module
!-----------------------------------------------------------------------
module interface_module
   implicit none

   interface
      function test(key, length) result(hash) bind(c, name="test")
         use iso_c_binding
         character(kind=c_char),dimension(*) :: key
         integer(c_size_t), value :: length
         integer(c_int32_t) :: hash
      end function test
   end interface

   abstract interface
      function function_hash_template(key, length)
         use iso_c_binding
         character(kind=c_char),dimension(*) :: key
         integer(c_size_t), value :: length
         integer(c_int32_t) :: function_hash_template
      end function function_hash_template
   end interface

contains

   function test_wrap(text) result(hash)
      use iso_fortran_env
      implicit none
      character(len=*),intent(in) :: text
      integer(int32) :: hash
      procedure(function_hash_template), pointer :: fun
      fun => test
      hash = int(hash_wrap(text, fun), int32)
   end function test_wrap


   !-----------------------------------------------------------------------
   !Function
   !-----------------------------------------------------------------------
   function  hash_wrap(text, fun) result(hash)
      use iso_c_binding
      implicit none
      character (len=*), target, intent(in) :: text
      procedure(function_hash_template), pointer :: fun
      integer(c_int32_t) :: hash
      character(kind=c_char), dimension(len_trim(text)+1) :: text_c
      integer(c_size_t) :: length

      text_c = f_to_c_string(text) ! convert to c string for compatibility

      length = len_trim(text) + 1
      write(*,*) "hash_wrap, length = ", length
      hash = fun(text_c,length)

   end function hash_wrap

   pure function f_to_c_string (f_string) result (c_string)
      use, intrinsic :: iso_c_binding, only: c_char, c_null_char
      implicit none
      character(len=*), intent(in) :: f_string
      character(len=1,kind=c_char), dimension(len_trim(f_string)+1) :: c_string
      integer :: n, i
      n = len_trim(f_string)
      do i = 1, n
         c_string(i) = f_string(i:i)
      end do
      c_string(n + 1) = c_null_char

   end function f_to_c_string

end module interface_module


!-----------------------------------------------------------------------
!Main program test_main
!-----------------------------------------------------------------------
program    test_main
   use interface_module
   implicit none

   write(*,*) test_wrap("1")

end program test_main

Instead of expected len = 2 I am getting always some uninitialized random len value in c function

./test_size_t_ifort_f.x
 hash_wrap, length =                      2
c key 1
c len 2977349904
c hash = 666
         666

ifort --version
ifort (IFORT) 16.0.2 20160204

 


Viewing all articles
Browse latest Browse all 2746

Latest Images

Trending Articles



Latest Images

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>