Я пытаюсь скомпилировать простую C ++ / Fortran Mixed программу, но у меня есть проблема с компоновкой. Я использую Visual Studio 2013 Ultimate и Intel Visual Fortran Compiler XE 14. Программа очень проста и копируется откуда-то из сети. Он имеет один файл C ++ и один файл Fortran
Файл C ++:
// Illustrate passing integer and floating point arrays
// from C++ to Fortran
#include <iostream>
using namespace std;
extern "C"{
int __stdcall SUMIT(int *, int*);
float __stdcall MEAN(float*, int*);
}
int main()
{
int iA[] = { 3, 5, 6, 7, 2, 3, 4, 5, 11, 7 }, iN = 10, iSum;
float fpA[] = { 1.2f, 3.f, 44.f, 2.5f, -1.3f, 33.44f, 5.f, 0.3f, -3.6f, 24.1f }, fpMean;
iSum = SUMIT(iA, &iN);
cout << "The Sum of iA is:" << iSum << endl;
fpMean = MEAN(fpA, &iN);
cout << "The Mean of fpA is:" << fpMean << endl;
return 0;
}
Фортран файл:
INTEGER FUNCTION SUMIT(IA,N)
INTEGER IA(1)
ISUM=0
DO 50 J=1,N
50 ISUM=ISUM+IA(J)
SUMIT=ISUM
RETURN
END
C
REAL FUNCTION MEAN(RA,N)
REAL RA(1)
SUM=0.
DO 50 J=1,N
50 SUM=SUM+RA(J)
IF(N.GT.0) MEAN=SUM/FLOAT(N)
RETURN
END
Для компиляции я создал проект библиотеки Fortran, который компилирует файл Fortran в статическую библиотеку, и другой проект C ++ с файлом C ++, который установлен как стартовый проект и зависит от проекта библиотеки Fortran. Я также включил сгенерированную библиотеку fortran в компоновщик проекта C ++.
Вывод компилятора / компоновщика:
1>------ Rebuild All started: Project: Lib1, Configuration: Debug Win32 ------
1>Deleting intermediate files and output files for project 'Lib1', configuration 'Debug|Win32'.
1>Compiling with Intel(R) Visual Fortran Compiler XE 14.0.3.202 [IA-32]...
1>Source1.f
1>Creating library...
1>
1>Build log written to "file://D:\work\Lib1\Debug\BuildLog.htm"1>Lib1 - 0 error(s), 0 warning(s)
2>------ Rebuild All started: Project: Test1, Configuration: Debug Win32 ------
2> Source.cpp
2>Source.obj : error LNK2019: unresolved external symbol _SUMIT@8 referenced in function _main
2>Source.obj : error LNK2019: unresolved external symbol _MEAN@8 referenced in function _main
2>D:\work\Lib1\Debug\Test1.exe : fatal error LNK1120: 2 unresolved externals
========== Rebuild All: 1 succeeded, 1 failed, 0 skipped ==========
Кто-нибудь имеет представление о том, что я могу делать неправильно?
Вы объявили функции в C с атрибутом stdcall. Этот компилятор Fortran без дополнительных директив или опций компиляции не использует это соглашение о вызовах. Избавьтесь от ключевых слов __stdcall. Могут быть и другие различия.
Гораздо лучшим способом обеспечения совместимости вашего кода на языке Fortran и C является использование функции взаимодействия на языке C на языке Fortran 2003 — в этом случае, как минимум, вы бы применили суффикс BIND (C) к объявлениям процедур на языке Fortran, предоставив соответствующую привязку имя через спецификатор NAME = этого суффикса. Есть и другие шаги, которые вы можете предпринять, чтобы сделать интерфейс более надежным и портативным. Есть много примеров ответов на вопросы на этом сайте с тегом fortran-iso-c-binding.