Fortran与C函数指针互操作的结果错误

问题描述

我有一个C程序,该程序在静态lib中调用Fortran子例程。该子例程将指向在C中实现的回调的函数指针作为参数。一个最小的示例如下所示:

Fortran代码

subroutine fortran_function(input,c_function) bind(c)
    use,intrinsic :: iso_c_binding
    implicit none
    real(c_float),value,intent(IN) :: input
    type(c_funptr),intent(IN),value :: c_function
    abstract interface
        subroutine callback(a,b) bind(c)
            USE iso_c_binding,only: c_float,c_int
            integer(c_int),value :: a
            real(c_float),value :: b
        end subroutine callback
    end interface
    procedure(callback),pointer :: c_proc
    
    call c_f_procpointer(c_function,c_proc)
    
    call c_proc(1_c_int,input)
    if (input > 1.0) call c_proc(2_c_int,input)
end subroutine fortran_function

C代码

#include <stdio.h>

typedef void (*c_function)(int,float);
void fortran_function(float,c_function);

void callback(int a,float b)
{
    printf("a=%d,b=%.1f\n",a,b);
}

int main()
{
    fortran_function(0.0,&callback);
    fortran_function(5.0,&callback);
}

如果我对此进行编译(在Windows上为Intel和MSVS),则一切正常,并且得到了预期的输出

a=1,b=0.0
a=1,b=5.0
a=2,b=5.0

但是,我最后想针对一个PowerPC(使用gfortran和gcc-variant交叉编译器)。程序在那里编译而没有警告(-Wall),但产生输出

a=1,b=0.0
a=2,b=5.0

这很奇怪,因为对于第一次调用,该流永远不应进入if-body。显然不管怎么说,它还是这样做的,但是甚至会为输入打印正确的值。

在Ubuntu上使用:

powerpc-linux-gnu-gfortran test.f90 -c -Wall -pedantic
ar cr test.lib test.o

我已经检查过的内容

  • if (input > 1.0)代替if (input > 1.0_c_float)不能解决问题
  • 函数指针上使用按引用传递而不是按值立即崩溃(在Windows上运行正常)
  • 优化(在C和Fortran方面)都不能解决问题
  • 所有类型均为4字节sizeof(real)=sizeof(real(c_float))=sizeof(integer)=sizeof(integer(c_int))(与C相同)

有人知道什么可能导致此问题吗?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)