7

Fortran アプリケーションでネットワーク機能を呼び出せるようにしたいと考えています。私の上司は、C と Fortran を使用する代わりに、Fortran ですべてを行うように私に求めています。Windows で PGI の Fortran コンパイラを使用するバージョンのアプリケーションを既に作成しています。Linux に移行しており、おそらく Linux のコンパイラを使用する予定です。現在、gfortran を使用しています。

これらのネットワーク呼び出し用のインターフェイスを作成し、すべてをコンパイルしてリンクします。以下のコードは、インターフェイスと定数がモジュール内にあることを除いて、私がやっていることと似ています。

PROGRAM MAIN

    INTEGER,PARAMETER  ::AF_INET = 2
    INTEGER,PARAMETER  ::SOCK_STREAM = 1
    INTEGER,PARAMETER  ::IPPROTO_TCP = 6

    INTERFACE
      FUNCTION socket(domain,type,protocol)
        INTEGER  ::socket,domain,type,protocol
      END FUNCTION
    END INTERFACE

    sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)
    WRTIE(*,*)"Socket returned: ",sock

END PROGRAM

プログラムを実行すると、ソケット関数が失敗して -1 が返されます。何が起こっているのかよくわかりません。コマンドラインにライブラリを追加していないので、デフォルトのライブラリと正しくリンクしていると思います。を使用してコンパイルします

gfortran -o MAIN_PROGRAM MAIN_PROGRAM.f90 -fno-underscoring
4

2 に答える 2

10

Fortran 2003 で導入された ISO_C_Binding を使用して、C ライブラリ機能にアクセスできます。これは、最もクリーンで移植性の高いオプションです。Gfortranのドキュメントには、他のベンダーのマニュアルと同様に、詳細が記載されています。Fortran 90 用に POSIX へのインターフェースを実装することを目的としたプロジェクトもいくつかあります: fortranposixおよびposix90。しかし、私が言ったように、F2003 機能を使用した適切な C-Binding インターフェースがおそらく最もクリーンなオプションです。fortranwikiも参照してください。

編集: ISO-C-Binding グルーを追加したコードを次に示します (gfortran 4.4.5 でテスト済み)。

program testsocket
  use, intrinsic ::  iso_c_binding

  implicit none

  interface
    function socket(domain, type, protocol) bind(c, name="socket")
      use, intrinsic :: iso_c_binding
      integer(kind=c_int) :: socket
      integer(kind=c_int), value :: domain, type, protocol
    end function socket
  end interface

  integer :: sock

  sock = socket(2_c_int, 1_c_int, 6_c_int)

  write(*,*) "Socket returned: ", sock

end program testsocket
于 2012-04-24T22:16:15.300 に答える
0

これが推測です。あなたは科学または工学の大学院生で (コンピューター サイエンスやコンピューター エンジニアリングではありません)、上司は 1950 年より前に生まれました。もしそうなら、私はあなたの立場に立っていました (ただし、私の場合は Fortran 77 を使用する必要がありました)。 . あなたの痛みが分かります。

おそらくご存じのとおり、Fortran では C のようにヘッダー ファイルを使用して関数呼び出しのプロトタイプを作成しません。引数の型がチェックされていない場合、ヘッダーなしで Fortran 関数を呼び出すことができます。

ただし、この問題があります。または、以前はこの問題がありました。私の最近の経験は数年前のものです。C と比較して、GNU Fortran は各関数の名前の前に隠しアンダースコアを追加します。また、関数名を小文字にします。

readelf -aプログラムはここであなたを助けることができます. Fortran コンパイラが生成するオブジェクト ファイルで使用します。socketシンボルの出力を調べます。私の記憶が正しければ、_socketそこに が表示されます。

C の名前を使用してラッパー関数を作成する場合でも、C をまったく使用できない場合は、_socket()次に何をすべきかわからないことを認めます。その場合、狭い場所で立ち往生する可能性があります。いずれにせよ、頑張ってください。

更新: 以下の @MSB のコメントをお勧めします。

于 2012-04-24T21:05:19.370 に答える