2013-12-18 3 views
1

Я пытаюсь передать один массив размера из FORTRAN программы C.Невозможно передать массив из FORTRAN на C

Функция C называется, но ценности, которые она держит являются мусором. Но если я пытаюсь вызвать ту же функцию с помощью целочисленной переменной, я могу передать требуемое значение. Может ли кто-нибудь помочь мне с этим?

код я использую похож на этот

Файл: fortran_prog.f

program test 
    real*4 :: a(4) 
    data a/1,2,3,4/
    call test_func(a) 
end program test 

Файл: c_prog.c

int test_func(double a[]) { 
    int i; 

    for(i=0;i<4;i++) { 
     printf("%f\n",a[i]); 
    } 

    return 0; 
} 
+0

С какой платформой и конкретными компиляторами это связано? – wallyk

+0

Я запускаю их на Linux. Для программы C я использую gcc, а для FORTRAN я использую ifort – arunr

+4

. Способ сделать это в современную эпоху - с привязкой ISO ISO Fortran. Это часть стандарта языка Fortran и обеспечивает связь между переносимыми языками. Посмотрите тег http://stackoverflow.com/questions/tagged/fortran-iso-c-binding для многих примеров. –

ответ

1

Передача массивов между Fortran и C не является - тривиальная проблема. Конкретные компиляторы C и Fortran имеют значение.

Первая проблема, я вижу, что вы указываете double для соответствия real*4. Это, безусловно, неверно практически на всех платформах. Объявить функцию C как:

int test_func (float *a) 

Это может работать на некоторых платформах, хотя многие компиляторы Фортрана передать адрес в «дескриптора массива», а не сам массив. Проверьте документацию для компилятора Fortran.

+0

вы вызываете функцию, которая возвращает int как подпрограмму. объявите свою функцию C как возвращающую пустоту. – Anycorn

3
program test_Cfunc 

    use iso_c_binding 
    implicit none 

    interface 
     function test_func (a) bind (C, name="test_func") 
     import 
     integer (c_int) :: test_func 
     real (c_double), dimension (1:4), intent (in) :: a 
     end function test_func 
    end interface 

    real (c_double), dimension (1:4) :: a = [ 2.3, 3.4, 4.5, 5.6 ] 
    integer (c_int) :: result 

    result = test_func (a) 
    write (*, *) result 

end program test_Cfunc 

Использование Fortran в ISO C Binding, решение является портативным к парам трансляторов из того же поставщика, или их комбинаций, поддерживаемых поставщиком в Fortran компилятора. Вам не нужно понимать передающие соглашения конкретных компиляторов и не обрабатывать компилятор Fortran с помощью имени (это переопределение в соответствии с пунктом namebind). Вы описываете процедуру C для Fortran с блоком interface, указав типы C со значениями вида Fortran, указанными в привязке ISO C. Существует список типов типов в руководстве gfortran в главе «Внутренние модули». Также см. Главу «Программирование на смешанном языке». Поскольку привязка ISO C является частью языкового стандарта, эта документация является более общей, чем просто gfortran.