2012-06-29 44 views
4

我可以在Fortran中创建和使用动态二维数组(在77标准中)。现在,我想从Fortran程序的C函数中创建我的动态二维数组(使用'malloc'),并且可以通过Fortran程序访问它。在Fortran中,我还希望能够像(1:n,2)或(1,2)那样执行,并且还能够从Fortran子例程中传递和检索我的数组。请你能给我举个例子,并花时间解释(如果可能的话,我真的很感激它)记忆将如何对齐?万分感谢!此外,如果二维不可能直接工作,我很好用C函数创建单维数组,但从Fortran访问它,因为它是一个二维数组...谢谢!在c函数中创建和访问fortran动态数组

回答

3

不,你不能创建FORTRAN 77标准动态数组。

也不能使用malloc创建FORTRAN“动态”的阵列,任何试图从Fortran的释放它会导致崩溃。 (您可以在正常的方式为静态数组一个当然使用它。)

,如果你还明确要求FORTRAN 77,不要使用符号如(1:N,2)。这个标准不支持它。

在2003 Fortran语言有iso_c_binding,但没有像在FORTRAN 77中存在,只能通过假定大小的数组和压延用你的编译器采取任何名称的护理(即尾随在Fotran过程名称强调了从C)。

+0

我使用“分配”的声明? – tester

+0

'allocatable'声明从Fortran 90的onwords。 –

+0

支持,但从未尝试在任何情况下分配的Fortran分配数组中的温度。 –

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 
+0

感谢@Viktor!如果你能用Fortran和C代码展示一个完整的例子,我将不胜感激。至少是最初的几个步骤。谢谢! – tester

+1

+1的链接......我会考虑C是0索引的事实,FORTRAN是1索引的,至少同样重要。 –

+0

添加了实际代码的链接。对不起,现在没时间在这里重新输入。 –

2

为什么你必须做的FORTRAN 77这些事?它们在Fortran 2003或带有ISO C绑定的Fortran 95中要简单得多。几乎所有现有的Fortran编译器都采用ISO C绑定。该组合提供了您想要的功能,作为语言标准的一部分,因此以独立于平台和编译器的方式提供。

如果你仅仅需要创建动态数组,你可以这样做直接的Fortran 95可分配数组。如果您有不想更改的FORTRAN 77代码,则可以编写一些Fortran 95代码并将其混合。您可以将在Fortran 95中创建的可分配数组传递给另一个不声明为可分配的Fortran过程。

如果有某种原因,该阵列需要在C中创建,使用ISO C绑定来描述的Fortran C例程。使用malloc在C中创建的数组通过Fortran类型C_PTR传递给Fortran。然后使用Fortran内部子程序c_f_pointer将该存储连接到Fortran阵列。之后,您使用Fortran阵列,它与Fortran阵列相同。

这是事实,多维数组的索引顺序是语言之间不同。这是因为Fortran是列主要语言,C是行主要语言。但是,Fortran阵列没有必要被编入索引。这只是默认设置。您可以在声明中更改起始索引:实数组(0:99)。或为一个指针数组设置与C_F_POINTER与指针界限重新分配: 阵列(0:99)=>数组