6

Fortranモジュールには、配列とその名前を取り、データベースから(実際にはC関数を呼び出して)配列の形状を取得し、配列を一時バッファーにコピーし、バッファーを処理する別のC関数に渡す関数がありますそれ。この Fortran 関数の名前は、整数データの場合は fs_WriteData_i、実数の場合は fs_WriteData_f、倍精度の場合は fs_WriteData_d です。これらの関数はすべて、1 次元配列だけでなく、2D、3D、および 4D 配列も受け入れ、完全に機能します。これらのサブルーチンの 1 つのインターフェイスは次のとおりです。

subroutine fs_WriteData_d(fieldname, data)
    use, intrinsic :: iso_c_binding
    implicit none

    real(c_double), dimension(*) :: data
    character                    :: fieldname*(*)

    ! ...

end subroutine fs_WriteData_d

ユーザーがfs_WriteData_d('name', data)データを倍精度 (最大 4 次元配列) で呼び出した場合、このサブルーチンがジョブを実行します。

さて、質問へ: fs_WriteData と呼ばれる一般的なオーバーロードされたインターフェイスを提供したいので、

interface fs_WriteData
    module procedure fs_WriteData_i, &
                     fs_WriteData_f, &
                     fs_WriteData_d
end interface fs_WriteData

残念ながら、これは機能しません。コンパイラは、ユーザーが を呼び出すだけでは正しい実装を見つけることができないと述べていますfs_WriteData('name', data)。これは、これらすべての関数とのランクの不一致が原因です。

モジュールをより保守しやすくするために、すべての fs_WriteData_d_1d、fs_WriteData_d_2d、... サブルーチンをまったく同じ内容で書くことを避ける賢明な方法はありますか?

よろしくお願いします。

4

1 に答える 1

7

ある種。

ご存知のように、F2008の時点でのジェネリックコールの特定のプロシージャを選択するためのルールでは、特に要素プロシージャは別として、タイプ、種類、ランクの一致(いわゆるTKR互換)が必要です。データダミー引数はサイズが想定されていますが(特定のプロシージャを直接呼び出す場合は、ゼロ以外のランクの実際の引数に関連付けることができます)、TKR互換性の目的でランク1の引数と見なされます。

最近公開されたFortranとCのさらなる相互運用性に関する技術仕様(TS29113)には、想定ランクの概念が追加されています。実行可能部分内で何をするかに応じてfs_WriteData_d(Cに渡すことでできることはほとんどすべてです)、タイプ/種類/ランクの一致のルールが拡張され、想定されるランクの実際の引数またはダミーの引数が互換性があるかどうかに関係なく互換性がありますランクの。かなり重要な問題は、コンパイラのサポートです。現在、このTSをサポートしているコンパイラはないと思います。

F201Xより前の言語標準にコーディングするには、いくつかの可能性があります。

  • サポートするランクごとに一連のシンラッパーサブルーチンを記述します。これらのラッパーサブルーチンは、1Dフォームの特定のプロシージャを呼び出し、シーケンスの関連付けに依存して多次元配列を1D配列にマップします。

  • サブルーチンの本体を別のファイル内に配置し、そのファイルを各ランクのサブルーチンのスケルトンインターフェイス内に含めます。このアプローチでは、サブルーチンの本体内のコードが字句的にランクに依存しないことが必要です。場合によっては、コードをタイプに依存しない方法で記述し、サポートするさまざまなタイプに共通のインクルードファイルを使用することもできます。これにより、「コピーアンドペースト」コードの変更管理に関連する問題は解消されますが、INCLUDEされたファイルの処理は少し面倒な場合があります。

2つの組み合わせも適切な場合があります。

(3番目のオプションは、Cの相互運用性を使用して、ランクとタイプの組み合わせごとに記述されたインターフェイス本体のバインディング名を1つの実装手順のバインディング名に設定することですが、Cの(ab)使用かどうかはわかりません。相互運用性は合法です。)

さまざまなタイプのバリアントの一般的な命名が必要な場合は、別の可能性(ここでも、本文で何をしているかによって異なります)は、データ引数をISO_C_BINDING組み込みモジュールからC_PTRとして取得し、取得の要件をプッシュすることです。サブルーチンのクライアントコードに戻る実際の引数のC_LOC。

于 2013-01-21T08:37:00.133 に答える