Вызов Фортрана из C++-CLI

У меня есть подпрограмма на Фортране, FortranShake, и основная функция C++, HandShakingTest.cpp. Я пытаюсь вызвать подпрограмму на фортране из CLR C++.

Я получаю две партии ошибок. Давайте назовем их ERROR(1) и ERROR(2). Буду очень признателен, если вы поможете мне понять, почему происходят эти ошибки.

Когда я пытаюсь скомпилировать следующее: cl /clr HandShakingTest.cpp

Я получаю следующую ОШИБКУ (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

ОШИБКА (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

1 ответ

Ваша первая ошибка на самом деле ошибка компоновщика - без /c Переключатель командной строки вы компилируете и связываете за один шаг. Код Fortran или объектный код не были предоставлены.

Ваша вторая ошибка:

  • Вы указали (из-за упущения) несоответствие библиотек времени выполнения для C++ и Fortran. Вам необходимо решить, хотите ли вы использовать статическое связывание (по умолчанию для текущего (на сегодняшний день, но не обязательно со следующего месяца...) выпуска Intel Fortran для Windows) или динамическое связывание (по умолчанию для MS C++ компилятор). Возможно добавить /MD в командной строке ifort, которая определяет динамическое связывание.

  • Без параметров или директив компилятора, наоборот, эквивалентный идентификатор для процедуры Fortran в коде C, сгенерированный этим компилятором Fortran, является вариантом имени процедуры Fortran в верхнем регистре, т. Е. В коде C++ вызов процедуры FORTRANSHAKE. Если вы можете написать свой код Fortran в стандарте F2003, вы должны использовать возможности взаимодействия C этого языка (BIND(C,...)) управлять именем привязки C процедуры Fortran и обеспечивать согласование вызовов и т. д. выровнять.

  • Пустой аргумент подпрограммы Fortran имеет спецификатор типа DOUBLE PRECISION, который эквивалентен double в C++ для этой комбинации компиляторов, а не int, Опять же, F2003 представляет функции, которые могут сделать это выравнивание типов аргументов более надежным.

Другие вопросы по тегам