5月 2007 - 投稿数

諸般の事情で、UnManaged な FORTRAN77 から .NET Framework クラスライブラリを呼び出すことになり、Intel Visual Fortran 9.1 と Visual Studio 2005 の VC++ の静的リンクを試してみました。
(INTERFACE 宣言を除いて) Fortran ソースに手を加えなくても、動くようです。
これで旧資産の延命措置になるかも。

VS2005~ツールメニュー~オプションの設定
 プロジェクトおよびソリューション~VC++ディレクトリ
  ディレクトリを表示するプロジェクト=ライブラリファイルを選択して、ディレクトリ一覧の最後に IVF の %LIB% を追加
  (デフォルトインストールの場合は \Program Files\Intel\Compiler\Fortran\9.1\IA32\Lib)

VS2005 新規作成~プロジェクト
 プロジェクトの種類=Visual C++ CLRコンソールアプリケーション 名前=cmain
 ソリューションエクスプローラにてソリューションを選択して、追加~新しいプロジェクト、プロジェクトの種類=Intel Fortran Project~スタティックライブラリ 名前=fortlib

ソリューションのプロパティ設定
 共通プロパティ~プロジェクト依存関係にて、プロジェクト=cmain、依存先=fortlib にチェックを入れてOKボタン

cmainプロジェクトのプロパティ
 C/C++~コード生成~構造体メンバのアライメント=4byte
  リンカ~入力~追加の依存ファイルに libifcorertd.lib を追加

fortlibプロジェクトのプロパティ
 Fortran~データ~共通要素のアライメント=4byte
  プロジェクトのSource Filesにて、追加~新しい項目、テンプレート=Source

----------------------------------------------------------------------------------------------------
// cmain.cpp : メイン プロジェクト ファイルです。

#include "stdafx.h"
#include <string.h>

using namespace System;

extern "C" void C2F(double *dArg);  // C++→Fortranのプロトタイプ。必ず大文字
extern "C" void f2c(void);          // Fortran→C++のプロトタイプ
typedef struct tagCommon1 {         // COMMONメンバのプロトタイプ。実体はFortran側で宣言、メモリ確保される
    int i;
    double d;
    char c[12];
} Common1;
extern "C" Common1 COMMON1;         // COMMONの宣言。

int main(array<System::String ^> ^args)
{
    // COMMONの初期化
    COMMON1.i = 1;
    COMMON1.d = 2.0;
    strcpy_s(COMMON1.c,sizeof(COMMON1.c),"Managed C++");

    double dArg;
    C2F(&dArg);
    Console::WriteLine(L"Fortran引数戻り={0}",dArg);

    // Fortran側で変更したCOMMONの結果
    Console::WriteLine(L"COMMON:integer={0}",COMMON1.i);
    Console::WriteLine(L"COMMON:double={0}",COMMON1.d);
    Console::WriteLine(L"COMMON:character={0}",gcnew String(COMMON1.c));

    return 0;
}

void f2c(void)
{
    Console::WriteLine(L"Fortran から呼ばれた Managed C++ 関数");
}

----------------------------------------------------------------------------------------------------
C
C FORTLIB.FOR
C

      SUBROUTINE C2F(ARG)
      INTERFACE
        SUBROUTINE F2C[C,ALIAS:'_f2c']
        END
      END INTERFACE
      REAL*8 ARG
      COMMON/COMMON1/I,D,C
      INTEGER*4 I
      REAL*8 D
      CHARACTER*12 C
     
      WRITE(6,*) 'MANAGED C++から呼ばれた FORTRAN SUBROUTINE'
C
C
 引数を設定する
C

      ARG = 10.D0
C
C COMMONの値を設定する
C
      I = I + 1
      D = D + 1.D0
      C = 'FORTRAN 77'
C
C FORTRAN→MANAGED C++
C
      CALL F2C()
      RETURN
      END