从Fortran调用C函数时GNU编译器分段错误,但英特尔编译器运行良好

时间:2016-04-05 12:35:27

标签: fortran

我学会了通过以下链接从Fortran调用C函数

Fortran/C Mixing : How to access dynamically allocated C array in Fortran?

我有一个" SIGSEGV"在使用GNU编译器进行编译时,将int更改为double中的call_fc(相应代码也已更改)时出现问题,而英特尔编译器正常。

C代码和Fortran代码如下:

///从Fortran调用的C函数

#include "stdio.h"
#include "math.h"

void call_fc(double *(*x), int s)
{
    double *y = malloc(s*sizeof(double));
    int i;
    for(i=0; i < s; i++)
    {
        y[i]= sin((double)i);//(double)((i+1)*(i+1));
    }
    *x = y;
}

/// Fortran主程序调用C函数

PROGRAM FORT_C
   use iso_c_binding
   IMPLICIT NONE

   interface
      subroutine call_fc(pX,s) bind(C,name='call_fc')
         import
         integer(c_int)     :: s
         type(c_ptr)        :: pX
      end subroutine
   end interface

   integer(c_int)                   :: i
   integer(c_int)                   :: s
   real(c_double), pointer          :: X(:)
   type(C_ptr)                      :: pX

   s=100

   call call_fc(pX,s)
   call c_f_pointer(pX,X,(/s/))

   do i=1,s
   write(*,*)  i, x(i)
   end do

END program

对于GNU编译器(线程模型:posix gcc版本4.9.2 20150212(Red Hat 4.9.2-6)(GCC) ),我使用以下命令编译它:

gcc -c test.c -o testc.o
gfortran -c test.f90 -o testf.o
gfortran testc.o testf.o -o testg.x
./testg.x

Image_Output_Calling_C_From_Fortran_GNU_compiler

顺便说一句,英特尔编译器的命令是:

icc -c test.c -o testc.o
ifort -c test.f90 -o testf.o
ifort testc.o testf.o -o testi.x
./testi.x

请帮助我使用GNU编译器的正确选项,或者修改两个编译器都接受的程序。非常感谢你!

更正后

/// test.c

#include <stdio.h>
#include <math.h>
#include <stdlib.h>

void call_fc(double *(*x), int s)
{
    double *y = malloc(s*sizeof(double));
    int i;
    for(i=0; i < s; i++)
    {
        y[i]= sin((double)i);
    }
    *x = y;
}

/// test.f90

PROGRAM FORT_C
   use iso_c_binding
   IMPLICIT NONE

   interface
      subroutine call_fc(pX,s) bind(C,name='call_fc')
         import
         integer(c_int),value :: s
         type(c_ptr)          :: pX
      end subroutine
   end interface

   integer(c_int)           :: i
   integer(c_int)           :: s
   real(c_double), pointer  :: X(:)
   type(C_ptr)              :: pX

   s = 10
   call call_fc(pX,s)
   call c_f_pointer(pX,X,(/s/))

   do i=1,s
      write(*,*)  i, x(i)
   end do

END program

1 个答案:

答案 0 :(得分:1)

该计划存在多个问题。首先只是一个C。你是否禁用了编译器警告?我的gcc抱怨说

> gfortran value.c value.f90
value.c: In function ‘call_fc’:
value.c:7:17: warning: incompatible implicit declaration of built-in function ‘malloc’ [enabled by default]
     double *y = malloc(s*sizeof(double));
             ^

这可能不会导致一台计算机崩溃,但可能很容易在其他地方造成。

你应该包括

#include <stdlib.h>

其他包含也应位于尖括号<>中,而不应位于""中,因为它们是标准C标题。

Fortran部分在界面中存在问题。你想要

integer(c_int), value :: s

因为C函数需要按值的参数。另一个参数没有value,因为它是一个通过引用传递的指针,而C有一个指向指针的指针。