1

假设我在 Fortran 中有以下子例程

    子程序执行(例程)

        隐式无

        外部 :: 例程
        真实(种类=8)::水库

        调用例程(2.0d0,res)
        print *, "Fortran 结果: res = ", res

    结束子程序执行

该子例程接收一个外部例程作为参数。现在,假设这个例程是用 C 编写的,并且我还需要从 C 中调用 Fortran 例程exec。像这样:

    无效操作(双x,双* f){
        *f = pow(x, 2);
    }

    无效的主要(){
        执行_(操作);
    }

我知道,如果我不是传递一个外部子例程,而是传递一个整数、双精度或其他常规类型,它会起作用,但此代码会返回分段错误。有什么方法可以将C外部类型的参数传递给 Fortran?

4

1 回答 1

0

这有效,您必须使用指针:

void op(double *x, double *f) {
    *f = pow(*x, 2);
}

void main() {
    exec_(&op);
}

subroutine exec(routine)

    implicit none

    external     :: routine
    real(kind(1.d0)) :: res

    call routine(2.0d0, res)
    print *, "Fortran Result: res = ", res

end subroutine exec

不要使用kind=8它不会声明 8 字节实数,而是类型编号为 8 的处理器相关类型。即使是旧的和非标准的real*8也会更好。

但最好使用 Fortran 2003 c 互操作性和iso_c_binding模块:

f.f90

子程序 exec(routine_c) bind(C,name="exec_") 使用 iso_c_binding 隐式无

    abstract interface
        subroutine sub(a,b) bind(C)
          use iso_c_binding
          implicit none
          real(c_double),value :: a
          real(c_double) :: b
        end subroutine
    end interface

type(c_funptr),value :: routine_c
real(c_double) :: res
procedure(sub),pointer :: routine

call c_f_procpointer(routine_c,routine)

call routine(2.0d0, res)
print *, "Fortran Result: res = ", res

结束子程序执行

抄送

#include <math.h>
void op(double x, double *f) {
    *f = pow(x, 2.0);
}

int main() {
    extern void exec_(void (*) (double, double *));
    exec_(&op);
    return 0;
}

汇编:

 gfortran c.c f.f90 -Wall -g -fbacktrace -fcheck=all
cc1: warning: command line option ‘-fbacktrace’ is valid for Fortran but not for C [enabled by default]
cc1: warning: command line option ‘-fcheck=all’ is valid for Fortran but not for C [enabled by default]
 ./a.out 
 Fortran Result: res =    4.0000000000000000   
于 2013-04-27T09:45:18.447 回答