【发布时间】:2018-01-15 20:17:18
【问题描述】:
在 Fortran 中,我有一个 C_FLOAT 数组,它被声明为输入参数:
SUBROUTINE Main(n,myCArray) BIND(C, NAME = 'Main')
INTEGER(C_INT), INTENT(IN ) :: n
REAL(C_FLOAT), INTENT(INOUT), dimension(n) :: myCArray
CALL PrintTheArray(n,myCArray)
END SUBROUTINE MAIN
正如Main子程序主体中所写,我想将myCArray传递给另一个子程序,如下所示:
SUBROUTINE PrintTheArray(n,theCArray)
INTEGER(C_INT), INTENT(IN ) :: n
REAL(C_FLOAT), INTENT(INOUT), dimension(n) :: theCArray
print *, theCArray(1), theCArray(2)
END SUBROUTINE PrintTheArray
通过这样做,我从不打印数组的正确值。但是,如果我打印子程序Main() 中的值,则这些值是正确的。出了什么问题,我该如何解决?
在 Fortran 中传递 C_FLOAT 数组确实没有问题。所以这个问题是错误的。我在这里提供了一个最小、完整和可验证的示例(我使用 Ubuntu、GNU Fortran (GCC) 6.3.0、gcc (GCC) 6.3.0):
文件名为FORTRANFunc.f90的Fortran代码
MODULE TEST
USE, INTRINSIC :: ISO_C_Binding
IMPLICIT NONE
contains
subroutine CALLFORTRAN(n,myArray) BIND (C, NAME = 'CALLFORTRAN')
INTEGER(C_INT), INTENT(IN ) :: n
REAL(C_FLOAT), INTENT(IN ) :: myArray(n)
CALL PRINTARRAY(n,myArray)
end subroutine CALLFORTRAN
subroutine PRINTARRAY(n, myArray)
INTEGER(C_INT), INTENT(IN ) :: n
REAL(C_FLOAT), INTENT(IN ) :: myArray(n)
print *, myArray(1), myArray(2)
end subroutine PRINTARRAY
END MODULE TEST
文件名为main.c的C代码
#include <stdio.h>
#include <stdlib.h>
extern void CALLFORTRAN(int* n, float* myArray);
int main()
{
int n=2;
float* myArray = (float*) malloc(2);
myArray[0] = 0.5;
myArray[1] = 1.5;
CALLFORTRAN(&n,myArray);
return 0;
}
你可以编译:
gfortran -c FORTRANFunc.f90
gfortran main.c FORTRANFunc.o -o test
然后你执行:
./test
结果应该是:
0.500000000 1.50000000
【问题讨论】:
-
你能为我们创建一个minimal reproducible example 吗?
-
确实,当它没有打印正确的值时,它会打印什么?
Main()中的值是否正确?需要详细的问题说明和minimal reproducible example。 -
我感觉问题出在 C 代码上。通常,在 Fortran 子例程之间传递 C_FLOAT 数组是没有问题的。
-
第二行通常是USE ISO_C_BINDING。 C 是按引用传递还是按值传递?
-
@Holmz 如果上面的某个模块已经使用了
use iso_c_binding,那么它绝对没有理由。use iso_c_binding不会以任何方式更改调用约定(按值/引用传递)。
标签: c fortran parameter-passing fortran-iso-c-binding