Я пытаюсь передать структуру из фортрана в C, где структура в фортране имеет выделяемое. Я хотел бы разместить массив внутри структуры в fortran и прочитать его на C. Однако, когда я пытаюсь распечатать выделенный массив в CI, появляется ошибка сегментации сообщения об ошибке (ядро сброшено). Я использую компилятор Intel версии 19.0.1.144.
Я относительно новичок в C, поэтому для проверки этой идеи я выделил одномерный массив в фортране и передал его в C. Это очень хорошо работает. В коде Фортрана вы можете видеть, что ff является размещаемым массивом и ему назначено измерение ii (равное 5). Я инициализирую массив ff и использую указатель типа (C_ptr) для хранения адреса массива ff. Я печатаю ff в C, и он печатает правильные значения ff, которые составляют 14.7,15.7,16.7,17.7,18.7. Используя ту же идею, я объявил struct data1 с целым числом ival, реальным cval и размещаемой переменной dval. Я выделяю указатель pdata для типа структуры data1. Я выделяю указатель и массив dval. Я вызываю fortran в моем C Main, чтобы напечатать значения struct, и получаю ошибку, когда я печатаю массив d (или dval). Кроме того, значения значений ival и cval в C неверны.
SUBROUTINE Simulation(ii,ffp,cdata) BIND(C)
use, intrinsic :: iso_c_binding
integer(kind=4), intent(in) :: ii
type(C_PTR), intent(out) :: ffp
real (C_double), dimension(:), allocatable, target, save :: ff
integer(kind=4) :: err, i
Type :: data1
Integer :: ival
Real :: cval
Real (C_double), dimension(:), allocatable :: dval
end Type data1
type(C_ptr), intent(out) :: cdata
type(data1), Target, save :: tdata
type(data1), pointer :: pdata
!Allocating memory for pdata:
Allocate(pdata,stat=err)
print *,'allocate returned: ',err
!Allocating memory for dval:
allocate(pdata%dval(ii),stat=err)
print *,'allocate returned: ',err
!Allocating memory for ff:
allocate(ff(ii),stat=err)
print *,'allocate returned: ',err
ffp = C_LOC(ff(1))
cdata = C_Loc(pdata)
pdata%ival = 4
pdata%cval = 17.6
pdata%dval(1) = 1.2
pdata%dval(2) = 1.2*2
pdata%dval(3) = 1.2*3
pdata%dval(4) = 1.2*4
pdata%dval(5) = 1.2*5
print*,"ival = ",pdata%ival
print*,"cval = ",pdata%cval
print*,"davl(1) = ",pdata%dval(1)
print*,"davl(4) = ",pdata%dval(4)
write(*,*) '#Fortran address of ff:', LOC(ff(1))
write(*,*) '#Fortran address: pdata', LOC(pdata)
write(*,*) 'size of ff =',sizeof(ff)
write(*,*) 'size of pdata =',sizeof(pdata)
do i=1,ii
ff(i) = i + 13.7d0
end do
END SUBROUTINE SIMULATION
Код c, вызывающий подпрограмму fortran:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
struct temp {int ival; float cval; double *d;};
void simulation(int *ii, double **ff, struct temp *data2);
int main()
{
int ii = 5;
double *ff;
struct temp data2;
int i;
simulation(&ii,&ff,&data2);
printf("#C address of ff: %d\n", ff);
printf("#C address of data2: %d\n", data2);
printf("Size of ff in C is %d\n", sizeof(ff));
for (i=0; i<ii; i++)
printf("ff[%d] = %f\n",i,ff[i]);
printf("data ival %d \n",data2.ival);
printf("data cval %f \n",data2.cval);
printf("data dval(1) %f \n",data2.d[0]);
printf("data dval(4) %f \n",data2.d[3]);
return 0;
}
Выход на терминале
bash-4.2$ ./a.out
allocate returned: 0
allocate returned: 0
allocate returned: 0
ival = 4
cval = 17.60000
davl(1) = 1.20000004768372
davl(4) = 4.80000019073486
#Fortran address of ff: 26650144
#Fortran address: pdata 26636320
#Fortran address: tdata 7054304
size of ff = 40
size of pdata = 80
size of tdata = 80
#C address of ff: 26650144
#C address of data2: 26636320
Size of ff in C is 8
ff[0] = 14.700000
ff[1] = 15.700000
ff[2] = 16.700000
ff[3] = 17.700000
ff[4] = 18.700000
data ival 26636320
data cval 0.000000
Segmentation fault (core dumped)
Вы видите, что ival равен 4, а cavl равен17.6 в фортране, но в C ival - это адрес структуры data2, cval = 0.0. Я не могу понять, что происходит не так. Мои извинения за вставку всего кода на форуме, я не мог найти способ объяснить это лучше. Буду признателен за любые предложения / помощь в этом отношении. Заранее спасибо!