how can I access a C pointer from fortran?

c, fortran, fortran-iso-c-binding

Solution

You have to declare STAT somehow. If you start to play with dynamic memory allocation, staying in FORTRAN 77 is hopeless. Maybe someone id able to come up with some solution, but this is the smallest change I found possible. It uses Fortran 2003 interoperability with C.(Maybe Cray pointer solution would be shorter, but non-standard)

USE ISO_C_BINDING

IMPLICIT NONE


INTEGER(C_INT) KEY,SIZE,ADDR,I
DATA KEY  / 777 /
DATA SIZE / 64 /
!DATA ADDR / Z'b76fb000' /
INTEGER,POINTER  :: STAT(:)
TYPE(C_PTR) :: STATPTR

CALL CALL_FC(KEY, ADDR, SIZE, STATPTR)

call C_F_POINTER(STATPTR,STAT,(/SIZE/))

PRINT *, 'stat is : '
DO I=1,SIZE
  PRINT *,STAT(I)
END DO

! CAN I ACCESS TO STAT LIKE THIS?
!DO I=1,10
!STAT(I) = STAT(I) + 5
!WRITE (*,*) STAT(I)
!END DO
END

I am getting some error from your C part, which I didn't check. Also I do not know exactly, what the program is supposed to do.

However I really encourage you to use modern Fortran features. Most important is ISO_C_BINDING for interoperability between C and Fortran. Also forget `DATA` statements and use variable initialization.

Quick translation to a more modern Fortran:

  use iso_c_binding

  implicit none

  interface
    subroutine call_fc(key,addr,size,status) bind(C,name='call_fc_')
      import
      integer(c_int) :: key  !intents should be added
      integer(c_int) :: addr
      integer(c_int) :: size
      type(c_ptr) :: status
    end subroutine
  end interface



  integer(c_int) :: key = 777, size=64,addr,i
  integer(c_int),pointer  :: stat(:)
  type(C_ptr) :: statptr

  call call_fc(key, addr, size, statptr)

  call c_f_pointer(statptr,stat,(/size/))

  print *, 'stat is : ',stat

end

Problem

I allocated value to status array like this : status[i] += 1; and I like to access to this array from fortran how can I access to this array? for example I want to change the value of STAT from fortran like this : STAT(2)=3 is this possible? c source ``` #include <stdio.h> #include <stdlib.h> #include <sys/shm.h> #include <sys/stat.h> void call_fc_ (int *key, int *addr, int *size, int *status) { int i; int shmid; void* shared_addr; //printf("first ptr = %p\n", *addr); shmid = shmget (*key, *size, IPC_CREAT | IPC_EXCL | 0666); if (shmid == -1) { printf("shmget is failed!\n"); exit(0); } shared_addr = (void*) shmat(shmid, 0, 0); status = (int*)shared_addr; //printf("status ptr = %p\n", status); int data_size = *size/sizeof(int); for(i=0; i<data_size;i++) { status[i] += 1; printf("%d th value : %d \n", i, status[i]); } } ``` fortran source ``` IMPLICIT NONE INTEGER*8 KEY,SIZE,ADDR DATA KEY / 777 / DATA SIZE / 64 / !DATA ADDR / Z'b76fb000' / CALL CALL_FC(KEY, ADDR, SIZE, STAT) PRINT *, 'stat is : ', STAT ! CAN I ACCESS TO STAT LIKE THIS? !DO I=1,10 !STAT(I) = STAT(I) + 5 !WRITE (*,*) STAT(I) !END DO ``` I have been tested this code and I refered to good answers to this question. but I got an segmentation fault error when I tried to do like this : ``` integer(c_int) :: key = 777, ssize = 64, addr integer, pointer, dimension(:) :: stat type(c_ptr) :: statptr !DATA KEY / 777 / !DATA SIZE / 64 / print *, 'before stat size = ', size(stat) call call_fc(key, addr, ssize, statptr) !print *, 'statptr = ', statptr call c_f_pointer(statptr, stat, [ssize]) print *, 'after stat size = ', size(stat) stat(1) = 111 <== stat(2) = 222 stat(3) = 333 print *, 'stat : ', stat ``` can you recognize what the matter is?

Original source