在 Fortran 和 C 之间交换数组
Exchanging array between Fortran and C
我有以下 C 和 Fortran 代码,我想在其中交换一些数据
FUNCTION exchange_data(data) bind(c,name='exchange_data')
use iso_c_binding
integer(kind=c_int) :: exchange_data
real(kind=c_double), intent(inout), dimension(*) :: data
END FUNCTION exchange_data
....
WRITE(*,*), "Sent data to C"
DO I=1,NumBl
DO J=1,WindSpeedCoordNr
WRITE(*, FMT2), GLOBAL_COORD_ALONG_BEAM(I, J, :)
END DO
END DO
cflag = exchange_data(GLOBAL_COORD_ALONG_BEAM)
WRITE(*,*), "Received data from C"
DO I=1,NumBl
DO J=1,WindSpeedCoordNr
WRITE(*, FMT2), GLOBAL_COORD_ALONG_BEAM(I, J, :)
END DO
END DO
以及以下测试 C 代码:
int exchange_data(double* positions)
{
printf("Received data from Fortran");
bladepositions = positions;
for (int i = 0; i < numbld; i++) {
for (int j = 0; j < datapointnr; j++) {
printf("[");
for (int k = 0; k < 3; k++) {
printf("%5.4f ", bladepositions[3 * datapointnr * k + 3 * j + i]);
windspeedalongblade[3 * datapointnr * k + 3 * j + i] = 1.0;
}
printf("]\r\n");
}
}
positions = windspeedalongblade;
printf("Data will be send from C");
for (int i = 0; i < numbld; i++) {
for (int j = 0; j < datapointnr; j++) {
printf("[");
for (int k = 0; k < 3; k++) {
printf("%5.4f ", positions[3 * datapointnr * k + 3 * j + i]);
}
printf("]\r\n");
}
}
return 0;
}
这有以下输出
Sent data to C
-18.6593 -29.1175 137.0735
-18.8588 -29.1308 137.0803
-19.0582 -29.1441 137.0871
Received data from Fortran
[-18.6593 -29.1175 137.0735 ]
[-18.8588 -29.1308 137.0803 ]
[-19.0582 -29.1441 137.0871 ]
Data will be send from C
[1.0000 1.0000 1.0000 ]
[1.0000 1.0000 1.0000 ]
[1.0000 1.0000 1.0000 ]
Received data from C
-18.6593 -29.1175 137.0735
-18.8588 -29.1308 137.0803
-19.0582 -29.1441 137.0871
我似乎可以将数据传输到 C 函数,但不能返回到 Fortran 代码。我怎样才能做到这一点?
问题是下面一行:
positions = windspeedalongblade;
不会将 windspeedalongblade
永久分配给 positions
(参见 here 按值传递和按引用传递之间的区别)。
为此,您需要将位置作为指向数组的指针传递:
int exchange_data(double** positions)
{
...
*positions = windspeedalongblade;
printf("Data will be send from C");
for (int i = 0; i < numbld; i++) {
for (int j = 0; j < datapointnr; j++) {
printf("[");
for (int k = 0; k < 3; k++) {
printf("%5.4f ", *positions[3 * datapointnr * k + 3 * j + i]);
}
printf("]\r\n");
}
}
return 0;
}
但在这种情况下,您必须确保 windspeedalongblade
保持不变,直到您开始使用 positions
。
更简单的解决方案是保留函数原样并直接分配 positions
数组的值:
int exchange_data(double* positions)
{
printf("Received data from Fortran");
bladepositions = positions;
for (int i = 0; i < numbld; i++) {
for (int j = 0; j < datapointnr; j++) {
printf("[");
for (int k = 0; k < 3; k++) {
printf("%5.4f ", bladepositions[3 * datapointnr * k + 3 * j + i]);
windspeedalongblade[3 * datapointnr * k + 3 * j + i] = positions[3 * datapointnr * k + 3 * j + i] = 1.0;
}
printf("]\r\n");
}
}
printf("Data will be send from C");
for (int i = 0; i < numbld; i++) {
for (int j = 0; j < datapointnr; j++) {
printf("[");
for (int k = 0; k < 3; k++) {
printf("%5.4f ", positions[3 * datapointnr * k + 3 * j + i]);
}
printf("]\r\n");
}
}
return 0;
}
所以最后要看你想让positions
是一个数组还是只是一个指向数组的指针。从 Fortran 代码的外观来看,它似乎是一个数组,在这种情况下,第二种解决方案是最好的。
我有以下 C 和 Fortran 代码,我想在其中交换一些数据
FUNCTION exchange_data(data) bind(c,name='exchange_data')
use iso_c_binding
integer(kind=c_int) :: exchange_data
real(kind=c_double), intent(inout), dimension(*) :: data
END FUNCTION exchange_data
....
WRITE(*,*), "Sent data to C"
DO I=1,NumBl
DO J=1,WindSpeedCoordNr
WRITE(*, FMT2), GLOBAL_COORD_ALONG_BEAM(I, J, :)
END DO
END DO
cflag = exchange_data(GLOBAL_COORD_ALONG_BEAM)
WRITE(*,*), "Received data from C"
DO I=1,NumBl
DO J=1,WindSpeedCoordNr
WRITE(*, FMT2), GLOBAL_COORD_ALONG_BEAM(I, J, :)
END DO
END DO
以及以下测试 C 代码:
int exchange_data(double* positions)
{
printf("Received data from Fortran");
bladepositions = positions;
for (int i = 0; i < numbld; i++) {
for (int j = 0; j < datapointnr; j++) {
printf("[");
for (int k = 0; k < 3; k++) {
printf("%5.4f ", bladepositions[3 * datapointnr * k + 3 * j + i]);
windspeedalongblade[3 * datapointnr * k + 3 * j + i] = 1.0;
}
printf("]\r\n");
}
}
positions = windspeedalongblade;
printf("Data will be send from C");
for (int i = 0; i < numbld; i++) {
for (int j = 0; j < datapointnr; j++) {
printf("[");
for (int k = 0; k < 3; k++) {
printf("%5.4f ", positions[3 * datapointnr * k + 3 * j + i]);
}
printf("]\r\n");
}
}
return 0;
}
这有以下输出
Sent data to C
-18.6593 -29.1175 137.0735
-18.8588 -29.1308 137.0803
-19.0582 -29.1441 137.0871
Received data from Fortran
[-18.6593 -29.1175 137.0735 ]
[-18.8588 -29.1308 137.0803 ]
[-19.0582 -29.1441 137.0871 ]
Data will be send from C
[1.0000 1.0000 1.0000 ]
[1.0000 1.0000 1.0000 ]
[1.0000 1.0000 1.0000 ]
Received data from C
-18.6593 -29.1175 137.0735
-18.8588 -29.1308 137.0803
-19.0582 -29.1441 137.0871
我似乎可以将数据传输到 C 函数,但不能返回到 Fortran 代码。我怎样才能做到这一点?
问题是下面一行:
positions = windspeedalongblade;
不会将 windspeedalongblade
永久分配给 positions
(参见 here 按值传递和按引用传递之间的区别)。
为此,您需要将位置作为指向数组的指针传递:
int exchange_data(double** positions)
{
...
*positions = windspeedalongblade;
printf("Data will be send from C");
for (int i = 0; i < numbld; i++) {
for (int j = 0; j < datapointnr; j++) {
printf("[");
for (int k = 0; k < 3; k++) {
printf("%5.4f ", *positions[3 * datapointnr * k + 3 * j + i]);
}
printf("]\r\n");
}
}
return 0;
}
但在这种情况下,您必须确保 windspeedalongblade
保持不变,直到您开始使用 positions
。
更简单的解决方案是保留函数原样并直接分配 positions
数组的值:
int exchange_data(double* positions)
{
printf("Received data from Fortran");
bladepositions = positions;
for (int i = 0; i < numbld; i++) {
for (int j = 0; j < datapointnr; j++) {
printf("[");
for (int k = 0; k < 3; k++) {
printf("%5.4f ", bladepositions[3 * datapointnr * k + 3 * j + i]);
windspeedalongblade[3 * datapointnr * k + 3 * j + i] = positions[3 * datapointnr * k + 3 * j + i] = 1.0;
}
printf("]\r\n");
}
}
printf("Data will be send from C");
for (int i = 0; i < numbld; i++) {
for (int j = 0; j < datapointnr; j++) {
printf("[");
for (int k = 0; k < 3; k++) {
printf("%5.4f ", positions[3 * datapointnr * k + 3 * j + i]);
}
printf("]\r\n");
}
}
return 0;
}
所以最后要看你想让positions
是一个数组还是只是一个指向数组的指针。从 Fortran 代码的外观来看,它似乎是一个数组,在这种情况下,第二种解决方案是最好的。