Fortran と Managed C++ のリンク
Posted
2007年5月23日 19:50
投稿者
hiyamuta
諸般の事情で、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