Вызов функций C из фортрана

Я пытаюсь вызвать функции C с помощью фортрана (это нужно для проекта). Итак, сначала я пытался просто вызвать непараметризованную функцию void через фортран.

Пожалуйста, помогите мне устранить следующие ошибки в данном коде.

Код C для умножения матриц:

#include <stdio.h>


extern "C" 

{ void __stdcall mat();
}


void mat()
{
 int m, n, p, q, c, d, k, sum = 0;

  printf("Enter the number of rows and columns of first matrix\n");
 scanf("%d%d", &m, &n);

  int first[m][n];

  printf("Enter the elements of first matrix\n");

  for (  c = 0 ; c < m ; c++ )
   for ( d = 0 ; d < n ; d++ )
  scanf("%d", &first[c][d]);

  printf("Enter the number of rows and columns of second matrix\n");
  scanf("%d%d", &p, &q);

  int second[p][q];

 if ( n != p )
   printf("Matrices with entered orders can't be multiplied with each other.\n");
 else
 {
  printf("Enter the elements of second matrix\n");

  for ( c = 0 ; c < p ; c++ )
   for ( d = 0 ; d < q ; d++ )
     scanf("%d", &second[c][d]);

  int multiply[m][q];  

  for ( c = 0 ; c < m ; c++ )
 {
   for ( d = 0 ; d < q ; d++ )
   {
    for ( k = 0 ; k < p ; k++ )
    {
      sum = sum + first[c][k]*second[k][d];
    }

    multiply[c][d] = sum;
    sum = 0;
  }
}

   printf("Product of entered matrices:-\n");

  for ( c = 0 ; c < m ; c++ )
  {
    for ( d = 0 ; d < q ; d++ )
      printf("%d\t", multiply[c][d]);

    printf("\n");
  }
 }

 }

  int main()
{
 mat();
return 0;
 }

Кроме того, код для вызова функции mat из фортрана, который я написал:

  program mat_mult  !This is a main program.

  call mat()
  stop
  end

При выполнении файла C я получаю следующую ошибку:

matrix_mult.c:5: ошибка: ожидаемый идентификатор или ‘(’ перед строковой константой

При выполнении файла fortran с помощью компилятора F77 я получаю следующую ошибку:

/tmp/ccQAveKc.o: в функции MAIN__': matrix_mult.f:(.text+0x19): undefined reference tomat_' collect2: ld вернул 1 статус выхода

Пожалуйста, помогите мне определить ошибку/правильный код. Спасибо.


person user2403879    schedule 21.05.2013    source источник


Ответы (1)


Сначала несколько вещей

1) Я предполагаю, что вы используете компилятор C99, потому что написанный вами код C не будет работать на компиляторе C89.

2) extern "C" предназначен для программ на C++, а не для программ на C.

Не совсем уверен, какой компилятор вы используете. Просто предположим, что вы используете gcc и gfortran, поскольку похоже, что вы работаете в системе на базе Linux.

gcc просто добавляет начальный _ к символам: таким образом, мат становится _mat. gfortran добавляет к символам как начальный, так и конечный _: таким образом, мат становится _мат _.

Чтобы заставить C и Fortran говорить

а) Удалить основную функцию из кода C

б) Удалить объявление extern "C". Это объявление C++, которое сообщает компилятору, что подпрограмма mat не должна иметь никакого искажения имени.

c) Поскольку у вас нет никаких параметров, просто предположим, что _cdecl и замените void mat() на void mat(). Если вам нужно использовать stdcall, вам нужно скомпилировать с параметром --enable-stdcall-fixup. stdcall понадобится, если программа на Fortran должна передать параметры программе на C, но это другая игра. Вместо _mat_ компилятор генерирует mat@0

d) Ваша подпрограмма C теперь будет выглядеть так:

#include <stdio.h>
void mat_()
{
    ...
}

/* No main */

д) Поскольку подпрограмма mat не объявлена ​​в коде на Фортране, компилятору необходимо знать, что она является внешней.

program mat_mult
external mat
call mat()
stop
end

f) Скомпилируйте и слинкуйте (скажем, программа на C называется mat.c, а программа на фортране называется matmul.f)

gcc -g -c mat.c
gfortran -g matmul.f mat.o -o matmul

Вероятно, будет целая куча комментариев, рекомендующих вам использовать F2003 или F2008, но если вам сказали, что вы должны использовать F77, вы должны использовать F77.

person cup    schedule 26.05.2013