我学会了通过以下链接从Fortran调用C函数
Fortran/C混合:如何在Fortran中访问动态分配的C数组?
在使用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编译器(线程模型:posixgcc版本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;
}
///测试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
程序中存在多个问题。第一个只是一个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>
其他include也应该在尖括号<>
中,而不是在""
中,因为它们是标准的C头。
Fortran部分在接口方面存在问题。你想要
integer(c_int), value :: s
因为C函数需要按值的参数。另一个参数没有value
,因为它是通过引用传递的指针,而C有一个指向指针的指针。