2012-12-06 5 views
5

że przydzielone wartości do macierzy stanu, jak to:Jak mogę uzyskać dostęp do wskaźnika C z fortranu?

stan [b] + = 1;

i chciałbym, aby uzyskać dostęp do tej tablicy z Fortran
Jak mogę uzyskać dostęp do tej tablicy?
na przykład chcę zmienić wartość STAT z Fortran tak:

STAT (2) = 3

jest to możliwe?

c źródło

#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 źródło

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 zostały przetestowane ten kod, a ja skieruję do dobrej odpowiedzi na to pytanie. ale mam błąd winy segmentacji, gdy próbowałem zrobić tak:

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 

można rozpoznać co chodzi?

Odpowiedz

7

Musisz zadeklarować STAT w jakiś sposób. Jeśli zaczniesz grać z dynamicznym przydzielaniem pamięci, pozostawanie w FORTRAN 77 jest beznadziejne. Może ktoś jest w stanie zaproponować jakieś rozwiązanie, ale jest to najmniejsza zmiana, jaką udało mi się znaleźć. Wykorzystuje Fortran 2003 współdziałanie z C (Może rozwiązaniem wskaźnik Cray będzie krótszy, ale 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 

otrzymuję jakiś błąd z części C, która nie sprawdzałem. Również nie wiem dokładnie, co program ma robić.

Jednak naprawdę zachęcam do korzystania z nowoczesnych funkcji Fortran. Najważniejsze jest ISO_C_BINDING dla interoperacyjności między C i Fortran. Zapomnij również o instrukcjach DATA i użyj inicjalizacji zmiennych.

Szybkie tłumaczenie do bardziej nowoczesnej 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 
+4

+1: ale mam do etapu, gdzie myślę, że pomaga ludziom pisać FORTRAN77 te dni jest nieetyczne; Pomogę im je przepisać, ale nie ma dobrych powodów, aby pisać nowy kod w FORTRAN77. –

+1

Lepiej pop tam również blok interfejsu dla rutyny. OP powinien również zastąpić niestandardowy 'INTEGER * 8' przez' INTEGER (C_INT) ', w przeciwnym razie prawdopodobnie wystąpi niezgodność wielkości całkowitych w wielu obecnych systemach. – IanH

+0

Masz zdecydowanie rację z typem całkowitym, który jest niezgodny. –