c - 在 Fortran 和 C 之间交换数组

标签 c fortran fortran-iso-c-binding

我有以下 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 和 C 之间交换数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45834540/

相关文章:

fortran - 在 Fortran 牛顿法中传递附加参数

c++ - 将字符串数组从 Fortran 传递到 C/C++ DLL 并获取具有更改值的数组

c - 将 C 函数返回的 C 指针释放给 Fortran?

c - C代码的优化

c - AIX 6.1 : CORE DUMP - GDB "thread apply all bt full" returns NOTHING?

fortran - 从整数转换为实数(dp)时自动分配失败

c - 将 Fortran 零长度数组传递给 C 的正确方法是什么?

c - 在 C 中使用 Fortran 函数会导致启动时出现段错误

c - 如何在没有 Visual Studio 的情况下为 Windows 编写内核驱动程序?

c - 无法使用 Cassandra 的 C 驱动程序连接到 key 空间