У меня есть следующая подпрограмма Fortran с именем show_value
, которая вызывает функцию C с именем show_value
:
INTERFACE
SUBROUTINE show_value(variable) BIND(C, name = "show_value")
USE, INTRINSIC :: iso_c_binding
TYPE(*) :: variable
END SUBROUTINE
END INTERFACE
Функция C show_value
:
void show_value(const void *variable)
{
printf("%d\n", *(int *) variable);
}
Подпрограмма Fortran хорошо работает при передаче ей скаляров. Пример:
INTEGER :: x
x = 12
call show_value(x)
Это вызовет функцию C show_value
и напечатает 12
, что правильно.
Теперь, согласно документации Фортрана, если вы хотите, чтобы подпрограмма show_value
принимала также массивы (любой размерности), а не только скаляры, строку TYPE(*) :: variable
следует заменить на TYPE(*), DIMENSION(..) :: variable
.
После внесения этого изменения при выполнении следующего кода Fortran:
INTEGER, DIMENSION(3) :: y
y(1) = 15
y(2) = 17
y(3) = 19
call show_value(y)
Функция C show_value
больше не печатает правильное сообщение (т.е. печатает случайные числа). Более того, я обнаружил, что адрес, который получает функция Си, на 528 ниже исходного (на Фортране). Чтобы подтвердить это:
void show_value(const void *variable)
{
printf("%d\n", *(int *) (variable + 528));
}
... который печатает 15
(правильное число).
Есть идеи, что здесь происходит?
Среда: Ubuntu 14.04 64 бит, gfortran 4.9