我可以在Fortran中创建和使用动态二维数组(在77标准中)。现在,我想从Fortran程序在C函数中创建我的动态二维数组(使用'malloc'),并能够通过Fortran程序访问它。在 Fortran 中,我还希望能够像 a(1:n,2) 或 a(1,2) 一样执行 smth,并且还能够从 Fortran 子例程中传递和检索我的数组。拜托,你能给我举个例子,并花时间解释(如果可能的话,我真的很感激)记忆将如何对齐?谢谢吨!此外,如果二维无法直接工作,我可以在 C 函数中创建一维数组,但从 Fortran 访问它,因为它是一个二维数组......谢谢!!!
不,您不能在 FORTRAN 77 标准中创建动态数组。
您也不能使用 malloc 创建 Fortran "动态"数组,任何从 Fortran 中释放它的尝试都会导致崩溃。(当然,您可以以正常方式将其用作静态数组。
此外,如果您明确请求 FORTRAN 77,请不要使用 a(1:n,2) 等表示法。此标准不支持它。
在Fortran 2003中iso_c_binding,但在FORTRAN 77中不存在类似的东西,您只能传递假定大小的数组并处理编译器使用的任何名称重整(即来自C的Fotran过程名称中的尾随下划线)。
最重要的区别是索引顺序。Fortran 使用数学符号,因此第一个索引是列索引,第二个索引是行。C 是不同的,第一个索引是行。
宏对此进行了解释
#define AccessFortranArray(ArrayName, i,j) ArrayName[j][i]
要做类似 a(1:n, 2) 的事情不能在 C 中完成,只能创建临时数组并在循环中提取元素(不包括要提取一系列行的情况 - 在这种情况下,您可以在 C 中使用指针算法)
C <-> Fortran 互操作有很好的参考,像这样
这里也是一个多维示例: 将数组传递到/传出 Fortran
"还有一件事"。
C 函数的名称必须在末尾包含下划线才能在 Fortran 中可见。它们也必须是小写的。这一切都是指gcc/gfortran对。
还有一个。您已经告诉过您能够传递数组,因此您知道(Jim Balter 在评论中这样说)Fortran 数组是基于 1 的,C 数组是从 0 开始的。
第三个。如果你只需要一大块数据,那么不要弄乱链接设置和函数调用约定,而是使用 COMMON 块。
喜欢这个
/* C Code */
extern struct
{
double arr[100];
} thearr_;
还有福特兰:
real*8 arr(100)
common/TheArr/ arr
为什么一定要在 FORTRAN 77 中做这些事情? 在 Fortran 2003 或具有 ISO C 绑定的 Fortran 95 中,它们要容易得多。 几乎所有当前具有ISO C绑定的Fortran 95级别的Fortran编译器。 该组合提供所需的功能,作为语言标准的一部分,因此以独立于平台和编译器的方式提供。
如果您只需要创建动态数组,则可以直接在Fortran 95中使用可分配数组执行此操作。 如果你有不想更改的 FORTRAN 77 代码,你可以编写一些 Fortran 95 代码并混合两者。 可以将在 Fortran 95 中创建的可分配数组传递给另一个未将其声明为可分配数组的 Fortran 过程。
如果出于某种原因需要在 C 中创建数组,请使用 ISO C 绑定来描述 Fortran 中的 C 例程。 使用 malloc 在 C 中创建的数组将传递给 Fortran 类型为 C_PTR。然后,该存储连接到具有Fortran内部子例程c_f_pointer的Fortran阵列。 之后,您使用Fortran数组,它与Fortran数组相同。
的确,多维数组的索引顺序在语言之间是不同的。 这是因为 Fortran 是列主语言,而 C 是行主语言。 但是,Fortran 数组不必是一个索引数组。 这只是默认的。 您可以在声明中更改起始索引:实数组 (0:99)。 或者对于具有指针边界重新分配c_f_pointer的指针数组设置:数组 (0:99) => 数组