1

fortran を使用して C 関数を呼び出そうとしています (プロジェクトにはこれが必要です)。そのため、最初は、fortran を介してパラメーター化されていない 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;
 }

また、私が書いた fortran から関数 mat を呼び出すコードは次のとおりです。

  program mat_mult  !This is a main program.

  call mat()
  stop
  end

Cファイルを実行すると、次のエラーが発生します。

matrix_mult.c:5: エラー: 文字列定数の前に識別子または '(' が必要です

F77 コンパイラを使用して fortran ファイルを実行すると、次のエラーが発生します。

/tmp/ccQAveKc.o: 関数MAIN__': matrix_mult.f:(.text+0x19): undefined reference tomat_' collect2: ld が 1 つの終了ステータスを返しました

エラー/正しいコードを特定するのを手伝ってください。ありがとうございました。

4

1 に答える 1

1

最初にいくつかのこと

1) あなたが書いた C コードは C89 コンパイラでは動作しないため、C99 コンパイラを使用していると思います。

2) extern "C" は C++ プログラム用です。C プログラムではありません。

どのコンパイラを使用しているかよくわかりません。Linux ベースのシステムを使用しているように見えるため、gcc と gfortran を使用していると仮定します。

gcc は先頭に _ をシンボルに追加するだけなので、mat は _mat になります。gfortran は、先頭と末尾の両方に _ をシンボルに追加します。そのため、mat は _mat _ になります。

C と Fortran を対話させるには

a) C コードから main 関数を削除する

b) extern "C" 宣言を削除します。これは、ルーチン mat に名前マングリングが含まれてはならないことをコンパイラーに伝える C++ 宣言です。

c) パラメータがないので、_ cdecl と仮定して void mat() を void mat() に変更します。stdcall を使用する必要がある場合は、--enable-stdcall-fixup でコンパイルする必要があります。Fortran プログラムがパラメーターを C プログラムに渡す必要があるが、それは別の球技である場合、stdcall が必要になります。_mat _ の代わりに、コンパイラは mat@0 を生成します。

d) C ルーチンは次のようになります。

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

/* No main */

e) ルーチン mat は Fortran コードで宣言されていないため、コンパイラはそれが外部であることを認識する必要があります。

program mat_mult
external mat
call mat()
stop
end

f) コンパイルとリンク (たとえば、C プログラムは mat.c と呼ばれ、Fortran プログラムは matmul.f と呼ばれます)

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

F2003 または F2008 を使用することを推奨するコメントが大量にある可能性がありますが、F77 を使用する必要があると言われている場合は、F77 を使用する必要があります。

于 2013-05-26T21:23:38.087 に答える