2013-08-21 77 views
-1

我有一個Fortran子程序,FortranShake和一個C++主函數HandShakingTest.cpp。 我試圖從CLR C++調用fortran子例程。從C++調用Fortran - CLI

我收到兩批錯誤。我們稱它們爲ERROR(1)和ERROR(2)。如果你能幫助我理解這些錯誤發生的原因,我將非常感激。

當我嘗試用下面的編譯: CL/CLR HandShakingTest.cpp

我得到以下ERROR(1):

HandShakingTest.obj : error LNK2028: unresolved token (0A00030A) "extern "C" void __c 
ecl FortranShake(int &)" ([email protected]@[email protected]) referenced in function "int __ 
lrcall main(cli::array<class System::String^>^)" ([email protected]@[email protected] 
[email protected]@@Z) 
HandShakingTest.obj : error LNK2019: unresolved external symbol "extern "C" void __cd 
cl FortranShake(int &)" ([email protected]@[email protected]) referenced in function "int __c 
rcall main(cli::array<class System::String^>^)" ([email protected]@[email protected] 
[email protected]@@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 &)" ([email protected]@[email protected]@@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 &)" ([email protected]@[email protected]@@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 &)" ([email protected]@[email protected]) referenced in function "int __c 
lrcall main(cli::array<class System::String^>^)" ([email protected]@[email protected] 
[email protected]@@Z) 
HandShakingTest.obj : error LNK2019: unresolved external symbol "extern "C" void __cde 
cl FortranShake(int &)" ([email protected]@[email protected]) referenced in function "int __cl 
rcall main(cli::array<class System::String^>^)" ([email protected]@[email protected] 
[email protected]@@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 

回答

3

你的第一個錯誤實際上是一個鏈接錯誤 - 沒有你的編譯和鏈接/c命令行開關一步到位。沒有提供Fortran代碼或目標代碼。

你的第二個錯誤是因爲:

  • 您指定(通過省略)不匹配的運行時庫爲C++和Fortran語言的。您需要決定是否要使用靜態鏈接(Windows上的Intel Fortran的目前(截止今天,但不一定在下個月...)發佈的默認設置)或動態鏈接(默認爲MS C++編譯器)。也許將/MD添加到指定動態鏈接的ifort命令行。

  • 如果沒有編譯器選項或相反的指令,Fortran編譯器生成的C代碼中的Fortran過程的等效標識符就是Fortran過程名稱的大寫變體 - 即在C++代碼中調用過程FORTRANSHAKE 。如果您可以將Fortran代碼編寫爲F2003標準,則應該使用該語言的C互操作性功能(BIND(C,...))來控制Fortran過程的C綁定名稱,並確保調用約定等。

  • 所述的Fortran子程序的僞參數具有雙精度類型說明符,這相當於在C++ double用於編譯器的這種組合,不int。同樣,F2003引入了可以使參數類型的這種對齊更加健壯的功能。