2016-04-15 11 views
1

gfortranを使用してコードをコンパイルしようとしています。サブルーチンplumed_f_gcmdは私が何らかの問題を抱えている場所です。ここでは、コードサブルーチンの引数リストに構文エラーがあります

 call plumed_f_gcmd("setMDTimeUnits"//char(0),timeUnits) 
     call plumed_f_gcmd("setPlumedDat"//char(0),"plumed.dat"//char(0)) 
     call plumed_f_gcmd("setLogFile"//char(0),"PLUMED.OUT"//char(0)) 
     call plumed_f_gcmd("setNatoms"//char(0),natms) 
     call plumed_f_gcmd("setMDEngine"//char(0),"dlpoly1.90"//char(0)) 

の作品があるコンパイラは、次のエラーがスローされます:すべての

call plumed_f_gcmd("setPlumedDat"//char(0),"plumed.dat"//char(0 
                   1 
Error: Syntax error in argument list at (1) 

call plumed_f_gcmd("setMDEngine"//char(0),"dlpoly1.90"//char(0) 
                   1 
Error: Syntax error in argument list at (1) 

まず私はかなりサブルーチンで、第二の入力は一回数とすることができる方法を理解していません一度文字列ですか? '//char(0)'は何とか文字列を別のデータ型に変更しますか?誰かがこれを私に説明してもらえますか?

私の2番目の質問は、3行目(PLUMED.OUT)の場合でもエラーが発生しない理由です。

どのようにCとC++ラッパーも関係していますが、わかりません。

void plumed_f_gcmd(char*key,void*val){ 
    plumed_gcmd(key,val); 
} 
+3

許可された行の長さを超えているように見えます。これは固定形式のソース(ファイル拡張子/コマンドラインは何ですか?)を意味しますか? – francescalus

+0

ここでの固定形式では、72桁目以降の文字は無視されます。 – Gilles

+0

はい、LRiOの変更は破壊的です。私はそれらを元に戻しています。 – SergeyA

答えて

1

コメントで示唆したように、あなたのFortranコードが固定形式で書かれており、最初の72個の文字があるため

Error: Syntax error in argument list at (1)

が最も可能性の高い表示されるエラーメッセージ:これはCのサブルーチンでありますコンパイラによって処理されます。これを避けるには、任意の長さの行が可能な

gfortran -ffixed-line-length-none yourcode.f 

のようなオプションを試してください。エラーが(「PLUMED.OUT」との)三行目のために発生していない理由は、行が72文字以内であることはおそらくある(しかし非常に近い!)char(0)(ヌル文字)、このためのよう


null-terminated stringとしてCルーチンで処理できるように、Fortranストリングに接続されています。 Fortranの//は文字列連結(他の言語では"hello" + "world"に似ています)を表していますが、文字列を別のデータ型に変更する特別なものではありません。 plumed_f_gcmd()の第2引数は一度数にすることができ、(文字列の後、私はこのルーチンは、おそらく最初の引数(または「コマンド」)を読み込んで推測すると、いくつかのルーチンに適切な型キャストを作る理由については


詳細は元codeをご覧ください)。例えば、整数、実数、文字列変数は、同じルーチンsub()に渡されている場合、次の:

fort.f90:

program main 
    implicit none 
    integer  :: intval 
    real   :: realval 
    character(50) :: str 

    intval = 777 ; realval = 3.14 ; str = "world" 

    call sub("ShowInteger" // char(0), 100 ) 
    call sub("ShowInteger" // char(0), intval) 

    call sub("ShowReal" // char(0), 1.0 ) 
    call sub("ShowReal" // char(0), realval) 

    call sub("ShowString" // char(0), "hello" // char(0)) 
    call sub("ShowString" // char(0), trim(str) // char(0)) 
end 

sub.c:

#include <stdio.h> 
#include <string.h> 

void sub_ (char* cmd, void* ptr) 
{ 
    printf("command = %s\n", cmd); 

    if (strcmp(cmd, "ShowInteger") == 0) printf("int : %20d\n", *((int*)ptr)); 
    if (strcmp(cmd, "ShowReal" ) == 0) printf("float : %20.5f\n", *((float*)ptr)); 
    if (strcmp(cmd, "ShowString" ) == 0) printf("str : %20s\n", (char*)ptr); 
} 

コンパイル

gfortran -c fort.f90 
gcc -c sub.c 
gfortran fort.o sub.o 

結果

command = ShowInteger 
int :     100 
command = ShowInteger 
int :     777 
command = ShowReal 
float :    1.00000 
command = ShowReal 
float :    3.14000 
command = ShowString 
str :    hello 
command = ShowString 
str :    world 

(上記のCルーチンは、gcc/gfortran以外のコンパイラでは移植できないことに注意してください。移植性を高めるには、現代Fortranの相互運用性機能(例:page)を使用してください。

関連する問題