【问题标题】:Modifying a Fortran array in C在 C 中修改 Fortran 数组
【发布时间】:2017-06-15 09:05:56
【问题描述】:

在 Fortran 中,我有一个数组指定为:

dimension insv(*)

现在我想从 C 中编辑这个数组。 我设法通过使用 iso_c_binding 从 C 中读取数组:

  SUBROUTINE userroutine(insv)
  IMPLICIT NONE
  INTERFACE
  SUBROUTINE MODIFYARRAY(insv) BIND(C)
  USE, INTRINSIC::ISO_C_BINDING
     REAL(C_DOUBLE),DIMENSION(*), INTENT(INOUT) :: insv
  END SUBROUTINE MODIFYARRAY
  END INTERFACE

  dimension insv(*)

  WRITE(insv(0))
  call modifyarray(insv)
  WRITE(insv(0))
  END

我的 C 函数:

__declspec(dllexport) void modifyarray(double * insv)

但是在 C 中修改这个数组中的值要么崩溃,要么根本没有改变。

__declspec(dllexport) void modifyarray(double * insv)
{
    insv[0] = 1234.00;
}

我不确定我应该对 iso_c_binding 或 C 函数进行什么更改才能使其工作。

更多上下文:fortran 数组类型无法更改,因为维度变量是用户例程的参数,而不是在我的控制范围内,可以这么说。 进入fortran函数时数组已经被填满,但需要在C中修改。

【问题讨论】:

  • 请出示代码。尤其是整个 C 函数。见minimal reproducible example。以及如何在 Fortran 中调用它 - 包括变量声明。我们必须知道数组最初来自哪里。
  • 除非你有一些其他的隐式输入规则,否则insv 是一个整数数组。子例程期待一个真正的参数。
  • 将其更改为 INTEGER(C_INT),DIMENSION(*) 会出现以下错误:实际参数的类型与虚拟参数的类型不同。我还将C函数的参数更改为:int * insv
  • 显示完整代码。包括implicit none 并包括所有变量声明。
  • 您现在发布的子例程不是合法的 Fortran。它不会编译。 在粘贴之前测试代码!它必须是可编译的并且它必须重现问题。阅读minimal reproducible example 是必不可少的。

标签: c arrays fortran fortran-iso-c-binding


【解决方案1】:

假设:

  • insvreal(C_DOUBLE) 的数组
  • 你想写insv(而不是现在看来由insv定义的文件单元)
  • 调用程序将insv定义为一个包含10个组件的数组

一个可能的工作测试用例如下:

Fortran:

SUBROUTINE userroutine(insv)
    USE, INTRINSIC::ISO_C_BINDING
    IMPLICIT NONE
    INTERFACE
        SUBROUTINE MODIFYARRAY(insv) BIND(C)
            USE, INTRINSIC::ISO_C_BINDING
            REAL(C_DOUBLE),DIMENSION(*), INTENT(INOUT) :: insv
        END SUBROUTINE MODIFYARRAY
    END INTERFACE

    real(C_DOUBLE), dimension(*) :: insv

    WRITE(*,*) insv(1)
    call modifyarray(insv)
    WRITE(*,*) insv(1)
END

PROGRAM MAIN
    USE, INTRINSIC::ISO_C_BINDING
    real(C_DOUBLE) :: insv(10)
    insv = 2.d0
    call userroutine(insv)
END

C:

void modifyarray(double * insv)
{   
    insv[0] = 1234.00;
}   

【讨论】:

  • 您好,Franz,您的测试用例让我了解了问题所在。在 Fortran 中,数组的索引从 1 开始,而 C 从 0 开始。我在 C 端更改了错误的索引。非常感谢。
  • 在 Fortran 端,而不是 C 端。至少在您显示的不完整代码中。
猜你喜欢
  • 1970-01-01
  • 2019-03-18
  • 2011-07-21
  • 1970-01-01
  • 2015-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-29
相关资源
最近更新 更多