Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28447 Discussions

Calling Fortran function from C - issue with type(c_ptr) arguments and return values

dasmy
Beginner
688 Views
Hello,

I have got the following small mixed-language example:

pointertest_c.c:
[cpp]#include 
#include

extern void* func2(void* arg);

void func()
{
int32_t arg = 42;
int32_t* ptr;

ptr = &arg;

printf("before func2 - value: : %d\n", *ptr);
printf("before func2 - address: %p\n", ptr);
ptr = func2(ptr);
printf("after func2 - address: %p\n", ptr);
printf("after func2 - value of arg: %d\n", arg);
}[/cpp]

pointertest_f.f90:
[fortran]function func2(arg) bind(c)
   use iso_c_binding
   implicit none
   type(c_ptr), value :: arg
   type(c_ptr) :: func2
   integer(kind=C_INTPTR_T) :: address

   integer*4, pointer :: fptr

   address = transfer(arg, address)
   write(*,'("inside func2 - address: ", "0x",Z8.8)') address

   ! **** create fortran pointer from c-pointer and output the value that is pointed to
   call c_f_pointer(arg, fptr)
   write(*,'("inside func2 - value:   ", i0)') fptr
   ! ****

   func2 = c_null_ptr

end function




program pointertest
  use iso_c_binding

  interface
    subroutine func() bind(c)
     use iso_c_binding
     implicit none
     end subroutine
  end interface


  call func()

end program
[/fortran]

Compilation with:
[bash]icc -g -c pointertest_c.c
ifort -g -c pointertest_f.f90
ifort -g -o pointertest pointertest_c.o pointertest_f.o
[/bash]

Using ifort/icc version 11 on a SUSE Linux system.

So I have got a variable in C, create a pointer to it and pass this pointer to func2() in fortran. It shall create a fortran-pointer of its argument and print the value that is pointed to. Unfortunately, the program sigsegvs when calling c_f_pointer():

Output using ifort:
[bash]before func2 - value: : 42
before func2 - address: 0xbfaddd60
inside func2 - address: 0x0000002A
forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image              PC        Routine            Line        Source
pointertest        0804A052  Unknown               Unknown  Unknown
pointertest        08049EC0  Unknown               Unknown  Unknown
pointertest        0804A0CD  Unknown               Unknown  Unknown
pointertest        08049E51  Unknown               Unknown  Unknown
libc.so.6          B75D3705  Unknown               Unknown  Unknown
pointertest        08049D61  Unknown               Unknown  Unknown
[/bash]

The address that is printed shows, that obviously, the pointer is already dereferenced during the call. Its value is 42 instead of the adress of my 42-variable. Unfortunately, the same issue happens with the return value of func2(): When commenting the lines between the "! ****", the programme runs fine, but after the call to func2(), the return value is not (nil), but again the address of the 42-variable which itself has been set to zero:

Output for return value test using ifort:
[bash]before func2 - value: : 42
before func2 - address: 0xbf95d0e0
inside func2 - address: 0x0000002A
after  func2 - address: 0xbf95d0e0
after  func2 - value of arg:   0[/bash]
Obviously, here is also an erroneously additional level of pointer-(de)referencing.

To the best of my knowledge, the programme should comply with the fortran standard and using the gnu compiler, the programme works well:

Output using GNU:

[bash]before func2 - value: : 42
before func2 - address: 0xbfbeb968
inside func2 - address: 0xBFBEB968
inside func2 - value: 42
after func2 - address: (nil)
after func2 - value of arg: 42[/bash]
Unfortunately, I cannot avoid this structure of mutual calling in my production programme. It results from pthread_create(..)-calls, called from C and calling Fortran thread-functions.


Am I doing something wrong or is this a compiler bug?

Thank you in advance,

Mathias
0 Kudos
1 Solution
mecej4
Honored Contributor III
688 Views
Your post is rather long and has variants of code, so I found it hard to understand what you want to do and how you are doing it after reading your post a couple of times. After trying your code, I recognized one issue that you brought up and posted it as a new thread:

C-Interop Issue

View solution in original post

0 Kudos
2 Replies
mecej4
Honored Contributor III
689 Views
Your post is rather long and has variants of code, so I found it hard to understand what you want to do and how you are doing it after reading your post a couple of times. After trying your code, I recognized one issue that you brought up and posted it as a new thread:

C-Interop Issue
0 Kudos
dasmy
Beginner
688 Views
Thank you for the elaboration. Comparing with your description of the issue, I maybe have been a bit too unclear ;-)

I consider this as closed here and will follow the new discussion thread for finding a solution.

Regards,

Mathias
0 Kudos
Reply