0

私は、データベースの読み取りと書き込みを行うC++ラッパーを備えたFortran77で構成されるプログラムを持っています。アプリケーションの2つの部分は、Fortran共通ブロックのような名前のグローバルC /C++構造体を使用する場合に機能を使用してデータを共有します。C ++ / Fortran統合へのこのエイリアシングアプローチは、1)多くのコンパイラスイートで機能し、2)*not8標準であると確信しています。できるだけ標準コンポーネントを使用するようにコードを維持しようとしています。また、この統合は脆弱であることが証明されています。

utd.h:

/*************************************************************
 *  This struct must follow the common block points.
 *  See the Fortran include file points.i
 *************************************************************/
typedef struct ALIGN points
{
    double  point[3][MAX_PTS];
    double  edge[3][MAX_PTS];
    double  edgenorm[3][MAX_PTS];
    double  edgerho[MAX_PTS];
    int     nfacets[MAX_PTS];
    double  facet1[3][MAX_PTS];
    double  facet2[3][MAX_PTS];
    double  gaussk[MAX_PTS];
    int     sbstin[MAX_PTS];
    int     coatin[MAX_PTS];
    int     sbstout[MAX_PTS];
    int     coatout[MAX_PTS];
    int     ncorners[MAX_PTS];
    double  cnrpoint[3][MAX_CNRS][MAX_PTS];
    int     ncnredgs[MAX_CNRS][MAX_PTS];
    double  cnredge[3][MAX_CNREDS][MAX_CNRS][MAX_PTS];
    int     cnrsbst[MAX_CNREDS][MAX_CNRS][MAX_PTS];
    int     cnrcoat[MAX_CNREDS][MAX_CNRS][MAX_PTS];
    int     npoints;
} POINTS;

extern POINTS  points_;

utd.cpp:

POINTS  points_;

points.i:

  !  maxpnt  -  maximum number of points in a path.
  integer  maxpnt
  parameter ( maxpnt = 1000 )

  integer npoints, nfacets(maxpnt)
  integer ncorners(maxpnt), ncnredgs(maxpnt,maxcorners)
  integer sbstin(maxpnt), coatin(maxpnt)
  integer sbstout(maxpnt), coatout(maxpnt)
  double precision point(maxpnt,3)
  double precision edge(maxpnt,3), edgenorm(maxpnt,3)
  double precision edgerho(maxpnt)
  double precision facet1(maxpnt,3), facet2(maxpnt,3)
  double precision gaussk(maxpnt), cnrpoint(maxpnt,maxcorners,3)
  double precision cnredge(maxpnt,maxcorners,maxcnredges,3)
  integer cnrsbst(maxpnt,maxcorners,maxcnredges)
  integer cnrcoat(maxpnt,maxcorners,maxcnredges)

  common /points/ point, edge, edgenorm, edgerho,
 *                nfacets, facet1, facet2, gaussk,
 *                sbstin, coatin, sbstout, coatout,
 *                ncorners, cnrpoint, ncnredgs,
 *                cnredge, cnrsbst, cnrcoat,
 *                npoints

もっと良い方法はありますか?共通のブロックをモジュールに変換したいと思うかもしれません。次に、グローバル構造体を使用して共通ブロックをエイリアシングするこのビジネスは、窓の外にあると確信しています。C ++からFortranモジュールをどのように構築しますか?そのようなモジュールからどのようにデータを読み取りますか?

C ++ / Fortran統合についてのあなたのアドバイスは何ですか?

4

1 に答える 1

5

Fortran2003のISOCバインディングにより、CとFortranの相互運用性がFortran言語標準の一部になり、コンパイラーとプラットフォームが移植可能になります。Cの機能のみを使用する場合は、C ++で機能する可能性がありますが、完全に保証されているわけではありません。ソースファイル内で、または2つのバージョンの言語で記述されたルーチンを混合することにより、Fortran2003とFORTRAN77を混合できます。ISO Cバインディングは、構造体とモジュール変数をグローバル変数としてサポートしているため、目標を達成できます。これらは両方とも、gfortranマニュアルの混合言語プログラミングの章に示されています。(ISO Cバインディングはgfortranに固有のものではありません。これは、優れたドキュメントとして引用しています。)

共通ブロックもサポートされていますが、私はあなたに同意します。避けるのが最善です...共通ブロックはFORTRANストレージシーケンスとレイアウトを追加しますが、これは不要です。CとFortranの「構造」を手動で維持して同等の宣言をする方法がわかりません。それが脆弱性の理由である場合は、注意する必要があります(一般的な命令から両方を書き込むためのプログラムを作成することはできません)。少し簡単にする1つのアプローチは、変数を構造体に入れないことです...そうすると、新しい変数を間違えると、古い変数に影響を与える可能性が低くなり、間違いの認識やデバッグが容易になる可能性があります。

于 2012-08-04T19:25:00.320 に答える