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