2012-04-24 17 views
6

私はFortranアプリケーションでネットワーキング機能を呼び出せるようにしたいと考えています。私の上司は、CとFortranを使用するのではなく、Fortranですべてをやりたいと思っています。 WindowsでPGIのFortranコンパイラを使用してすでにアプリケーションのバージョンを完成させています。私たちはおそらくそのコンパイラを使うLinuxに移しています。今、私はgfortranを使用しています。ソケットプログラミング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 
+0

あなたはerrnoをチェックしようとしたことがありますか? –

答えて

8

あなたはISO_C_BINDINGの使用は、これはあなたが持っている最もクリーンでポータブルオプションで、Cライブラリの機能にアクセスするためのFortran 2003年に導入することができます。 Gfortran documentationには他のベンダーのマニュアルと同様にいくつかの詳細があります。 Fortran 90のPOSIXへのインタフェースを実装することを目指しているプロジェクトもいくつかあります:fortranposixposix90です。しかし、F2003の機能を使った適切なC-Bindingインターフェイスがおそらく最もクリーンなオプションだと言ったので、fortranwikiも参照してください。

編集:ここでは は(のgfortran 4.4.5でテスト)を加えISO-C結合性接着剤を使用してコードです:

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

ああ!私は私の問題を見る。私はsocket()が有効なオプションで呼び出されていないように、参照渡しの引数を渡しています。ありがとう! – hw12

0

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

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

しかし、私の最近の経験は数年前であるため、このトラブルがありました。 Cと比較して、GNU Fortranは各関数の名前に隠れたアンダースコアを付加します。また、関数名を小文字にしています。

readelf -aプログラムがお手伝いします。 Fortranコンパイラが出力するオブジェクトファイルで使用します。出力でsocketシンボルを探します。私の想起が正しければ、そこに_socketが表示されます。

実際にCを全く使用できない場合は、Cの名前が_socket()のラッパー関数を作成する場合でも、次に何をすべきか分かりません。その場合、窮地に陥っている可能性があります。いずれにせよ、幸運。

更新:以下の@ M.S.B.のコメントをお勧めします。

+6

haraldkiによって記述されたISO Cバインディングを使用して関数の命名を制御し、下線を避けることができます。 FortranとCを混在させることは、これまでよりもはるかに簡単で移植性が向上します。 –

+3

私は1982年生まれで、私は新しいプロジェクトのためにFortranをiseしています。私はCから多くのコードを翻訳しました。私は何か悪いですか? –

+0

@VladimirF:いいえ、何も悪いことはありません。Fortranは仕事をするツールで、仕事をするために使っています。よかったね。あなたが知りたいのであれば、私の経験は逆でした。私はFortran 77(現代のFortranでなくても)を使って、CやPerlがより適したものにする必要がありました。私は気にしなかった。私は支払われた、私はそれについて私の上司と議論したことはありません。私の上司がこの事例で正しい選択をしたと思うかどうか聞いても、私はそうは思わないと言います。あなたについては:Fortranに行ってください! – thb