Проблема с подключением программы Intel Visual Fortran к функции C ++

Я пытаюсь связать очень простую функцию C ++ с очень простой программой Intel Visual Fortran.

Программа на Фортране выглядит так В файле с именем VFTestBed.f90):

 program VFTestBed

integer pInteger

pInteger = 11

call SimpleTest1( pInteger )

end program

Интерфейсный блок Fortran выглядит следующим образом (в файле interfaces.f90):

MODULE INTERFACES

interface

subroutine SimpleTest1( pInteger)

!DEC$ATTRIBUTES DECORATE, ALIAS: "SimpleTest1"
integer pInteger

end subroutine SimpleTest1

end interface

END MODULE

Функция C ++ выглядит следующим образом (в файле cppresponder.cpp):

#include <windows.h>
#include <sstream>

void SimpleTest1(int pInteger);

void SimpleTest1(  int pInteger)

{

std::string pString = "";
std::string pTitle = "";

std::string pName = "SimpleTest1\0";

pString = "Integer was entered.";
pTitle = "In Routine: " + pName;

MessageBoxA(NULL, pString.c_str(), pTitle.c_str(), MB_OK |    MB_ICONINFORMATION);

}

Я исследовал эту проблему в Google и перепробовал множество десятков вариантов и комбинаций различных настроек, объявлений, украшений и т. Д., Но все безрезультатно. Действительно, многие из постов были длинными и довольно запутанными и часто, казалось, не приводили к успешному завершению.

Среди прочего я попробовал:

  1. сделать код C ++ .LIB
  2. сделать код C ++ .DLL
  3. с использованием различных форм! DEC $ ATTRIBUTES DECORATE, ALIAS: «SimpleTest1»
  4. используя BIND (C, …)
  5. используя простые псевдонимы
  6. используя украшенные псевдонимы
  7. использовал DUMPBIN, чтобы увидеть символы в .DLL
  8. используя преамбулу extern «C»
  9. компиляция в виде кода C (отключает все конструкции C ++)

и многое другое. Я перепробовал все то, что якобы сработало для других постеров, но безуспешно.

Независимо от того, что я делаю, я получаю сообщение об ошибке компоновщика LNK2019 о неразрешенном внешнем символе _SIMPLETEST1, указанном в функции _MAIN__

Согласно сайту Intel, я добавил в CppResponder.DLL так же, как добавление в исходный файл.

Если это имеет значение, я использую Visual Studio Enterprise 2017 и Intel Parallel Studio XE 2016 Update 4 composer Edition для Windows, все они работают на 64-разрядной машине с Windows 8.1.

Предполагая, что Intel Fortran действительно может вызывать функцию C ++ (я предполагаю, что это возможно), тогда я должен пропустить переключатель или настройку где-нибудь. Я настроил оба проекта на Fortran и C ++ со значениями по умолчанию, которые предоставляет Visual Studio. Оба проекта были настроены как Release | x86.

Конечно, это действительно не может быть так сложно сделать. Я потратил около 12 часов на это, и мне нечего показать. У меня десятилетний опыт работы с Fortran, но я довольно новичок в C ++.

Кто-нибудь делал это раньше и хотел бы рассказать мне, как ты это сделал?

Заранее спасибо,

Боб Кайзер

0

Решение

cppresponder.cpp

#include <iostream>

extern "C" void simpletest_(int* i){
std::cout << "cpp " << *i << '\n';
}

VFTestBed.cpp

 program VFTestBed

integer pInteger

pInteger = 11

call simpletest(pInteger)

end program

сборник:

g++ -c cppresponder.cpp; gfortran -c VFTestBed.f90; gfortran -o test.o cppresponder.o VFTestBed.o -l stdc++

Exec:

./test.o

выход

>cpp 11

Вам также могут понадобиться эти ключи компилятора

 g++ -c -Wpadded -Wpacked -malign-double -mpreferred-stack-boundary=8 cppresponder.cpp; gfortran -c -malign-double VFTestBed.f90
0

Другие решения

Моя благодарность ответчикам выше. Я попробовал их предложения, но ничего не получил.

Но после гораздо большего горя я нашел то, что сработало.

Fortran:

program VFTestBed

use INTERFACES

integer pInteger

pInteger = 11

call SimpleTest1( pInteger )

end programMODULE INTERFACES

interface

subroutine SimpleTest1( pInteger)

!DEC$ ATTRIBUTES  ALIAS:'?SimpleTest1@@YGXPAH@Z' :: SimpleTest1

integer pInteger

end subroutine SimpleTest1

end interface

END MODULE

и на стороне C ++:

#define WIN32_DEFAULT_LIBS
#include <windows.h>
#include <iostream>
#include <sstream>__declspec(dllexport) void SimpleTest1(int* pInteger);

void SimpleTest1(int* pInteger)

{

std::string pString = "";
std::string pTitle = "";

std::string pName = "SimpleTest1\0";

pString = "Integer entered = " + std::to_string(*pInteger);
pTitle = "In Routine: " + pName;

MessageBoxA(NULL, pString.c_str(), pTitle.c_str(), MB_OK |    MB_ICONINFORMATION);}

Заметные изменения:

  1. добавлен __declspec (dllexport)
  2. изменил int на int *
  3. добавил #define WIN32_DEFAULT_LIBS
  4. изменен с .DLL на .LIB
  5. использовал DUMPBIN, чтобы выяснить оформление имени в C ++
  6. в основную программу добавлены ИСПОЛЬЗОВАНИЕ ИНТЕРФЕЙСОВ
  7. в интерфейсе добавлено:! DEC $ ATTRIBUTES ALIAS: ‘? SimpleTest1 @@ YGXPAH @ Z’ :: SimpleTest1

Итак, все это, чтобы получить менее 30 строк кода для компиляции, компоновки и запуска! Sheesh!

15+ часов моей жизни я никогда не вернусь.

Так или иначе, это решено, и я надеюсь, что я спас будущего читателя от всей скорби, через которую я прошел. Я надеюсь, что кто-то найдет это полезным.

0

По вопросам рекламы [email protected]