【发布时间】:2016-04-06 08:02:46
【问题描述】:
我正在尝试将数组从 C/C++ 传递到 Fortran 2003 模块,并将计算值返回到 C/C++。我已经能够很好地传递和返回单个值(标量),但是来回获取 array 是很困难的。我发现了很多关于标量值的线程,并且我已经成功地完成了这些工作。
我已经按照我的工作标量函数对基于数组的函数进行了建模。
我正在使用 gcc/gfortran。
这是 Fortran 模块 (ConvertUnitsLib.f03)。
module ConvertUnitsLib
use :: iso_c_binding ! for C/C++ interop
real(c_double), bind(c) :: degF, degC
public DegCtoF
contains
!
! Convert temperature degrees Celsius Fahrenheit
!
real(kind = c_double) function DegCtoF(degC) result(degF) &
& bind(c, name = "DegCtoF")
real(c_double), intent(in), dimension(:) :: degC
real(c_double), dimension(size(degC)) :: degF
do i = 1, size(degC)
degF(i) = ( degC(i) * 1.8 ) + 32
end do
end function DegCtoF
! End of module
end module ConvertUnitsLib
还有 C/C++,(CFort.cpp)
#include <stdio.h>
#ifdef __cplusplus
extern"C" {
#endif
double DegCtoF(double *[]);
#ifdef __cplusplus
}
#endif
/**********************************************************************/
int main(int argc, char *argv[])
{
printf("C/C++ and Fortran together!\n");
double DegreesC[2] = {32, 64};
double DegreesF[2];
DegreesF = DegCtoF(&DegreesC);
printf("%3.1f [C] = %3.1f [F]\n", DegreesC, DegreesF );
return 0;
}
最后但同样重要的是,Makefile
# C++ directives
CC=g++
CFLAGS=-std=c++11
# Fortran directives
FC=gfortran
FFLAGS=-std=f2003
all: clean
$(FC) $(FFLAGS) -c -fcheck=all ConvertUnitsLib.f03
$(CC) $(CFLAGS) -c CFort.cpp
$(FC) $(FFLAGS) ConvertUnitsLib.o CFort.o -o convert
clean:
rm -f *.o
rm -f *.mod
【问题讨论】:
-
好吧,我不确定 Fortran,但在 C 和 C++ 中,传递数组(实际上是传递第一个元素的地址)会丢失所有大小信息,因此您的 Fortran 例程对数组包含的实际元素数。我希望有两个参数,数组(或指向缓冲区的指针)和元素的数量。
-
从您的标签中,我假设您使用的是 gfortran/gcc,但您能确认一下吗?传递假定的形状参数,例如
degC不是 Fortran 2003 C 互操作性的一部分,需要付出更多的努力。目前预计将成为 F2015(ISO TS)一部分的方面不受 gcc 的支持。在没有此类支持的情况下,请使用@PaulMcKenzie 的评论,并使用一个明确的形状数组,其中也传递了大小。 -
@francescalus,是的,我正在使用 gfortran/gcc。当您的意思是更多的努力时,我是否还需要传递数组的大小?我知道当 C 调用 Fortran 函数时,它通过指针传递标量值。我是否也只需要传递大小,然后它(Fortran)可以解决剩下的问题吗?
-
@francescalus,好吧,这是有道理的。我现在正在处理该代码,但如何将其从 Fortran 传递回 C?
-
@francescalus,让标量变量在语言之间移动的唯一方法是将它们声明为 public。
标签: c++ c arrays fortran fortran-iso-c-binding