将数组从 C/C++ 传递给 Fortran 并返回计算后的数组 [英] Pass arrays from C/C++ to Fortran and return a calculated array
问题描述
我正在尝试将数组从 C/C++ 传递到 Fortran 2003 模块并将计算值返回到 C/C++.我已经能够很好地传递和返回单个值(标量),但是来回获取数组证明是困难的.我发现了许多关于标量值的线索,并且我已经成功地使这些工作发挥作用.
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!\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
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!\n");
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]\n", i, DegreesC[i], DegreesF[i] );
}
return 0;
}
这篇关于将数组从 C/C++ 传递给 Fortran 并返回计算后的数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!