Я хочу вызвать функцию C ++ из основной программы F77. Я определил в основной программе:
DOUBLE PRECISION FC34F, bf_Fc34F
и сделать звонок как
FC34F = bf_Fc34F( temp )
Функция bf_Fc34F является функцией C в файле * .C и определяется как
double bf_Fc34F_( double T ){
T="some_mathematical_expression";
return T;
}
Я использую g ++ / gfortran и при компиляции файла * .C (g ++ -c * .C) к файлу * .o добавляется завершающий символ «_d» (я думаю, для «double»), что делает основная программа нет, и, таким образом, я получаю ошибку «неопределенная ссылка».
Кто-нибудь знает, как преодолеть эту проблему?
Вы должны работать с совместимостью — в основном с искажением имен — как со стороны Fortran, так и со стороны C ++:
extern "C"
bind(C)
и используя совместимые типыКод C ++:
#include<iostream>
using namespace std;
extern "C" {
double bf_Fc34F( double T ){
T=T*T;
cout << " from c++ - T: " << T << endl;
return T;
}
}
Код Фортрана:
program fc34f_test
double precision FC34F
interface
function bf_Fc34F(T) bind(C,name="bf_Fc34F")
use iso_c_binding
real(C_DOUBLE) :: bf_Fc34F
real(C_DOUBLE), value :: T
end function
endinterface
FC34F = bf_Fc34F(2.d0)
print*,"from Fortran - FC34F: ", FC34F
end program fc34f_test
Скомпилировать:
g++ -c fun.C ; gfortran -c main.f90 ; g++ fun.o main.o -o exe -lgfortran
Выполнить:
./exe
Ваш файл C ++ должен использовать extern "C"
отключить искажение имени в C ++:
extern "C" {
double bf_Fc34F_( double T ){
T="some_mathematical_expression";
return T;
}
} // extern "C"
Имя функции в файле объекта .o и способ отправки / получения параметров к нему зависят от выбранного соглашение о вызовах.
Вы можете настроить обе стороны вызова, как Вот.
Для C-функции добавить __stdcall:
double __stdcall bf_Fc34F_( double T ){
T="some_mathematical_expression";
return T;
}
в Фортране отметьте эту внешнюю функцию как STDCALL