gpt4 book ai didi

c - 如何从 Fortran 访问 C 指针?

转载 作者:太空狗 更新时间:2023-10-29 14:59:23 25 4
gpt4 key购买 nike

我像这样为状态数组分配值:

status[i] += 1;

我喜欢从 fortran 访问这个数组
我怎样才能访问这个数组?
例如,我想像这样从 fortran 更改 STAT 的值:

STAT(2)=3

这可能吗?

源码

#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]);
}
}

源代码

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

我已经测试了这段代码,我提到了这个问题的好答案。但是当我尝试这样做时出现了段错误:

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

你能认出这是怎么回事吗?

最佳答案

您必须以某种方式声明 STAT。如果你开始玩动态内存分配,留在 FORTRAN 77 是没有希望的。也许有人能够想出一些解决方案,但这是我发现的最小变化。它使用 Fortran 2003 与 C 的互操作性。(也许 Cray 指针解决方案会更短,但不是标准的)

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

我从你的 C 部分得到了一些错误,我没有检查。我也不清楚该程序应该做什么。

不过,我真的鼓励您使用现代 Fortran 功能。最重要的是 ISO_C_BINDING,用于 C 和 Fortran 之间的互操作性。也忘记 DATA 语句并使用变量初始化。

快速翻译成更现代的 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

关于c - 如何从 Fortran 访问 C 指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13739732/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com