データ収集ルーチンを一部のレガシー Fortran に追加しました。使いやすくするために、C でファイル i/o ルーチンを作成しました。
私はgccとgfortranを使用しています。
問題: C 関数への無害な呼び出しのように見える間に、いくつかの Fortran 変数名が上書きされています。
C 関数はすべて void 型、名前はすべて小文字、引数はすべてポインター、関数名はすべて末尾に「_」を含み、サブルーチンとして Fortran から呼び出されます。私は前にこれをやったことがあります。gfortran は、すべての Fortran シンボルを小文字に強制し、すべてのエントリ ポイントに「_」を追加して、同じ名前の C エントリ ポイントと区別します。
C ファイルの一部を次に示します。
#define MAXFILES 20
FILE *outfile[MAXFILES];
/* int2char_ generates a left zero padded string (*theChar) from an int
(*theInt), that is *numChar characters long. E.g, called from fortran:
string *5 arun
integer nrun
integer nnchar
nrun = 231
nchar = 4
call int2char (nrun, arun, nnchar)
c... returns '0231' in arun
*/
void int2char_ (int *theInt, char *theChar, int *numChar) {
int nchar;
nchar = *numChar;
if (nchar > 9) nchar = 9;
if (nchar < 1) nchar = 1;
sprintf(theChar, "%*.*d", nchar, nchar, *theInt);
return;
} // end of int2char
void openwrite_ (char *filename, int *unit) {
outfile[*unit] = fopen (filename, "w");
return;
} /* end of openWrite */
void closefile_ (int *unit) {
int closed;
if (outfile[*unit]) {
closed = fclose (outfile[*unit]);
}
return;
}
void writefirststr_ (char *string, int *unit) {
int printed;
printed = fprintf (outfile[*unit], "%s", string);
// printed = fputs (string, outfile[*unit]);
return;
}
踏まれる Fortran 変数の宣言は次のとおりです。
c...................
c"Display the mass matrix when DISMAT is set TRUE "
LOGICAL, save :: DISMAT
c...................
注: 私は元々volatile
、修飾子の代わりに宣言修飾子を使用していましたsave
。変わりはない。
呼び出しは次のとおりです。
c...................
c... build file name
numchar = 4
call int2char (nrun, filenumber, numchar)
begin = 1
end = len_trim(fileprefix)
filename(begin:end) = fileprefix
begin = end + 1
end = begin + 3
filename(begin:end) = filenumber
begin = end + 1
end = begin + 3
filename(begin:end) = fileext
begin = end + 1
filename(begin:begin) = char(0)
c... close open file
call closefile (lunit)
c... open file
call openWrite (filename, lunit)
c... write header(s)
call writeFirstStr (atime', lunit)
c...................
行を実行すると問題が発生しcall writefirstStr ('time', lunit)
ます。
atime
'time' にデータ化されcharacter*5
、明示的に null で終了する ですtime(5:) = char(0)
。ステップスルーしwritefirststr_()
ても問題はなく、正しい情報がファイルに書き込まれます。
の後に (gdb 経由で) return ステートメント (上記のコード フラグメントを含む fortran ルーチン内) にジャンプしてもcall openWrite (filename, lunit)
、問題はありません。
r を呼び出すwriteFirstSt
と、fortran 変数が上書きされますDISMAT
。DISMAT
また、上記の C 言語呼び出しを行うルーチンには含まれていないことにも注意してください。
私がまだ試していないのはsave
、すべての Fortran 変数で修飾子を使用することです。レガシー コードの量による論理的な問題です。
誰にも考えはありますか?