将数组从 C/C++ 传递到 Fortran 并返回计算的数组
我正在尝试将一个数组从 C/C++ 传递到 Fortran 2003 模块,并将计算值返回到 C/C++.我已经能够很好地传递和返回单个值(标量),但是来回获取 array 证明是困难的.我发现了很多关于标量值的线程,并且我已经成功地完成了这些工作.
I am trying to pass an array from C/C++ into a Fortran 2003 module and get the calculated values back into C/C++. I've been able to pass and return single values (scalars) just fine, but getting an array back and forth is proving difficult. I've found many threads on scalar values and I've been successful at making those work.
我已经按照我的工作标量函数对基于数组的函数进行了建模.
I've modeled my array based functions after my working scalar functions.
我正在使用 gcc/gfortran.
I am using gcc/gfortran.
这是 Fortran 模块 (ConvertUnitsLib.f03).
Here's the Fortran module (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)
And the 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!
");
double DegreesC[2] = {32, 64};
double DegreesF[2];
DegreesF = DegCtoF(&DegreesC);
printf("%3.1f [C] = %3.1f [F]
", DegreesC, DegreesF );
return 0;
}
最后但同样重要的是,Makefile
And last but not least, the 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
推荐答案
在 francescalus 确认之前,我要说的是,据我所知,这有点陈旧,互操作性不允许您尝试做与数组.此外,一些好习惯在编码时总是至关重要的.例如,在 fortran 中使用 implicit none
强制在使用所有变量之前声明它们.在语言允许的情况下使用命名常量,例如您在 fortran 中用作数组大小的 2
.
Before francescalus confirms it, I was going to say that from what I know that was a little bit old, the interoperability does not permit what you are trying to do with arrays.
In addition, some good habits are always critical when coding. For example using implicit none
in fortran to force the declaration of all variables before they are used. The use of named constant when the language permits it, for example the 2
that you are using as array size in fortran.
以下是您的代码的修改版本,它应该可以实现您想要实现的目标.
Below is a modified version of your code that should do something like what you want to achieve.
//Fortran
module ConvertUnitsLib
use :: iso_c_binding ! for C/C++ interop
!real(c_double), bind(c) :: degF, degC
implicit none
public DegCtoF
contains
!
! Convert temperature degrees Celsius Fahrenheit
!
subroutine DegCtoF(degC, degF, n)&
bind(c, name = "DegCtoF")
integer, intent(in) :: n
real(c_double), intent(in), dimension(n) :: degC
real(c_double), intent(out), dimension(n) :: degF
integer :: i
do i = 1, n
degF(i) = ( degC(i) * 1.8 ) + 32
end do
end subroutine DegCtoF
//C++
#include <stdio.h>
#ifdef __cplusplus
extern"C" {
#endif
double DegCtoF(double [], double [], const int *);
#ifdef __cplusplus
}
#endif
/**********************************************************************/
int main(int argc, char *argv[])
{
const int N = 2;
printf("C/C++ and Fortran together!
");
double DegreesC[N] = {32, 64};
double DegreesF[N];
DegCtoF(DegreesC, DegreesF, &N);
for(int i = 0; i<N; i++){
printf("%d : %3.1f [C] = %3.1f [F]
", i, DegreesC[i], DegreesF[i] );
}
return 0;
}
相关文章