0

Fortran サブルーチン FortranShake と C++ メイン関数 HandShakingTest.cpp があります。CLR C++ から fortran サブルーチンを呼び出そうとしています。

2 つのバッチのエラーが発生しています。それらを ERROR(1) と ERROR(2) と呼びましょう。これらのエラーが発生する理由を理解していただければ幸いです。

次のようにコンパイルしようとすると: cl /clr HandShakingTest.cpp

次の ERROR(1) が表示されます。

HandShakingTest.obj : error LNK2028: unresolved token (0A00030A) "extern "C" void __c
ecl FortranShake(int &)" (?FortranShake@@$$J0YAXAAH@Z) referenced in function "int __
lrcall main(cli::array<class System::String ^ >^)" (?main@@$$HYMHP$01AP$AAVString@Sys
em@@@Z)
HandShakingTest.obj : error LNK2019: unresolved external symbol "extern "C" void __cd
cl FortranShake(int &)" (?FortranShake@@$$J0YAXAAH@Z) referenced in function "int __c
rcall main(cli::array<class System::String ^ >^)" (?main@@$$HYMHP$01AP$AAVString@Syst
m@@@Z)
HandShakingTest.exe : fatal error LNK1120: 2 unresolved externals

次に、代わりに次のコマンドを使用してコンパイルしました。

ifort /c FortranShake.f //Which compiles fine
cl /c /clr HandShakingTest.cpp //compiles fine
cl /o test HandShakingTest.obj FortranShake.obj //ERROR(2) occurs

ERROR(2) は次のもので構成されます。

MSVCRT.lib(ti_inst.obj) : error LNK2005: "private: __thiscall type_info::type_info(cla
ss type_info const &)" (??0type_info@@AAE@ABV0@@Z) already defined in LIBCMT.lib(typin
fo.obj)
MSVCRT.lib(ti_inst.obj) : error LNK2005: "private: class type_info & __thiscall type_i
nfo::operator=(class type_info const &)" (??4type_info@@AAEAAV0@ABV0@@Z) already defin
ed in LIBCMT.lib(typinfo.obj)
MSVCRT.lib(merr.obj) : error LNK2005: __matherr already defined in LIBCMT.lib(_matherr
_.obj)
LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NOD
EFAULTLIB:library
HandShakingTest.obj : error LNK2028: unresolved token (0A00030A) "extern "C" void __cd
ecl FortranShake(int &)" (?FortranShake@@$$J0YAXAAH@Z) referenced in function "int __c
lrcall main(cli::array<class System::String ^ >^)" (?main@@$$HYMHP$01AP$AAVString@Syst
em@@@Z)
HandShakingTest.obj : error LNK2019: unresolved external symbol "extern "C" void __cde
cl FortranShake(int &)" (?FortranShake@@$$J0YAXAAH@Z) referenced in function "int __cl
rcall main(cli::array<class System::String ^ >^)" (?main@@$$HYMHP$01AP$AAVString@Syste
m@@@Z)
libifcoremt.lib(for_main.obj) : error LNK2019: unresolved external symbol _MAIN__ refe
renced in function _main
test.exe : fatal error LNK1120: 3 unresolved externals

HandShakingTest.cpp は次のとおりです。

#include "stdio.h"
#include <stdlib.h>
#include <Windows.h>
#using <System.DLL>
#using <System.Windows.Forms.DLL>

using namespace std;
using namespace System;
using namespace System::IO;
using namespace System::Diagnostics;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;

extern "C" {void FortranShake(int&);}

int main(array<System::String ^> ^args)
{
    Process^ testHand = gcnew Process();
    testHand->StartInfo->UseShellExecute = false;
    testHand->StartInfo->RedirectStandardInput = true;
    testHand->StartInfo->RedirectStandardOutput = true;
    testHand->StartInfo->ErrorDialog = true;

    int numDebug = 0;
    String^ returnedDebug = "Nothing";

    FortranShake(numDebug);

    StreamReader^ FromHandProcess = testHand->StandardOutput;
    StreamWriter^ ToHandProcess = testHand->StandardInput;

    String^ Line;

    Line = FromHandProcess ->ReadLine();

    if (Line->Equals("Enter Hand") )
    {
        Console::WriteLine(L"Hand Started!");
    }
    ToHandProcess ->WriteLine(numDebug.ToString());
    returnedDebug = FromHandProcess ->ReadLine();

    MessageBox::Show(returnedDebug);

    return 0;
}

Fortran サブルーチンは次のとおりです。

  SUBROUTINE FortranShake(GP_DEBUG)
  IMPLICIT DOUBLE PRECISION (A-H,O-Z)
  INN = 5

  WRITE(06,'(a)') 'Enter Hand'

  READ(INN,*) GP_DEBUG
  GP_DEBUG = GP_DEBUG + 55
  WRITE(06,*) GP_DEBUG

  RETURN
  END
4

1 に答える 1

3

最初のエラーは、実際にはリンカ エラー/cです。コマンド ライン スイッチがなければ、コンパイルとリンクを 1 つのステップで行うことができます。Fortran コードまたはオブジェクト コードは提供されていません。

2番目のエラーは次の理由によるものです:

  • C++ と Fortran に対して不一致のランタイム ライブラリを (省略して) 指定しました。静的リンク (Windows 上の Intel Fortran の現在のリリース (今日の時点で、必ずしも来月とは限りません...) のデフォルト) を使用するか、動的リンク (MS C++ のデフォルト)を使用するかを決定する必要があります。コンパイラ)。おそらく/MD、動的リンクを指定する ifort コマンド ラインに追加します。

  • コンパイラ オプションまたは逆の指令がない場合、Fortran コンパイラによって生成される C コードの Fortran プロシージャの同等の識別子は、Fortran プロシージャの名前の大文字の変形です。つまり、C++ コードではプロシージャ FORTRANSHAKE を呼び出します。Fortran コードを F2003 標準に従って記述できる場合は、その言語の C 相互運用機能 ( BIND(C,...)) を使用して、Fortran プロシージャの C バインディング名を制御し、呼び出し規約などを確実に調整する必要があります。

  • doubleFortran サブルーチンの仮引数には DOUBLE PRECISION 型指定子があります。これは、このコンパイラの組み合わせの C++ ではなく、と同等intです。繰り返しになりますが、F2003 では、この引数の型の配置をより堅牢にする機能が導入されています。

于 2013-08-21T21:25:52.050 に答える