将数组从 C/C++ 传递给 Fortran 并返回计算后的数组 [英] Pass arrays from C/C++ to Fortran and return a calculated array

查看:21
本文介绍了将数组从 C/C++ 传递给 Fortran 并返回计算后的数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将数组从 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆