【问题标题】:GNU compiler segmentation fault when calling C function from Fortran, but Intel compiler works well从 Fortran 调用 C 函数时出现 GNU 编译器分段错误,但 Intel 编译器运行良好
【发布时间】:2016-04-05 12:35:27
【问题描述】:

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

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

在使用 GNU 编译器进行编译时,将 call_fc 中的 int 更改为 double 时出现“SIGSEGV”问题(相应的代码也已更改),而 Intel 编译器很好。

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

【问题讨论】:

  • 整数必须由value 传递,可能存在相同问题的一些重复项。试试integer(c_int), value :: s
  • 不确定是否完全重复stackoverflow.com/questions/24726446/…
  • 立即解决!非常感谢弗拉基米尔 F!

标签: fortran


【解决方案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>

其他包含也应该在尖括号 &lt;&gt; 中,而不是在 "" 中,因为它们是标准 C 标头。

Fortran部分接口有问题。你想要的

integer(c_int), value :: s

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

【讨论】:

  • 非常感谢您指出这些问题!太棒了!
猜你喜欢
  • 1970-01-01
  • 2012-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-21
  • 2015-06-19
相关资源
最近更新 更多