2016-04-05 3 views
1

я научился вызывать функцию C из Fortran по следующей ссылкеGNU ошибки сегментации компилятор при вызове функции C из Fortran, но Intel компилятор работает хорошо

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

и у меня есть «SIGSEGV» проблема, когда изменяя int на double в call_fc (соответствующий код также изменяется) при компиляции с компилятором GNU, в то время как компилятор Intel в порядке.

код С и Fortran кода заключаются в следующем: функция

/// C для вызова из Fortran

#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 основная процедура вызова функции С

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 version 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

Кстати, команды с компилятором Intel являются:

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 
+0

Целое число должно быть передано с помощью 'value', возможно, существует дубликат с той же проблемой. Попробуйте 'integer (c_int), value :: s' –

+0

Не уверен, что точный дубликат http://stackoverflow.com/questions/24726446/how-to-call-ac-function-in-fortran-and-properly-pass- uint32-t-arguments –

+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.

Устранение проблемы со стороны Фортрана в интерфейсе. Вы хотите получить

integer(c_int), value :: s 

потому что функция C ожидает аргументы по значению. Другой аргумент не имеет value, потому что это указатель, переданный по ссылке, и C имеет указатель на указатель.

+0

Спасибо, что заметили эти проблемы! Потрясающие! –

Смежные вопросы