This topic is on the same line as this one:
https://fortran-lang.discourse.group/t/issues-interfacing-between-c-and-fortran/
I have access to a C++ function that returns a complex class object and I want to call it from Fortran.
The problem is that, apparently, the C++ complex class is incompatible with the C double complex type defined in the header file complex.h.
Browsing the web, the solution I found was to create a couple of wrapper functions which employ a C - C++ compatible structure that stores the data. As a minimal working example I created 3 files:
part1.cpp:
#include <complex>
using namespace std;
// Define a C-compatible struct for complex numbers
struct C_ComplexDouble {
double real;
double imag;
};
complex<double> fccp (const complex<double> &a)
{
return sqrt(a);
}
extern "C" C_ComplexDouble call_fccp(C_ComplexDouble a_c) {
complex<double> a_cpp(a_c.real, a_c.imag);
complex<double> result_cpp = fccp(a_cpp);
C_ComplexDouble result_c = {result_cpp.real(), result_cpp.imag()};
return result_c;
}
part2.c:
#include<complex.h>
// Define the C-compatible struct for complex numbers
typedef struct {
double real;
double imag;
} C_ComplexDouble;
extern C_ComplexDouble call_fccp(C_ComplexDouble a_c);
double complex fccp_ccpp(const double complex a)
{
C_ComplexDouble a_c= {creal(a), cimag(a)};
C_ComplexDouble res= call_fccp(a_c);
return CMPLX(res.real, res.imag);
}
parts12.f90:
program parts12
use, intrinsic :: iso_c_binding, only: dpc => c_double_complex
implicit none
complex(dpc) :: a, res
INTERFACE
complex(dpc) function fccp_ccpp(a) bind(c)
import :: dpc
complex(dpc), intent(in), value :: a
end function fccp_ccpp
END INTERFACE
write(*, '(a)', advance= 'no')'a= ' ; read(*,*)a
res= fccp_ccpp(a)
print'(2(a,g0),a)', 'fccp(a)= (', res%re, ',', res%im, ')'
end program parts12
The compilation sequence is:
$> g++/icpx -c part1.cpp
$> gcc/icx -c part2.c
$> gfortran/ifx parts12.f90 part1.o part2.o
The executable successfully evaluates the square root of the complex number with both gfortran and ifx compilers.
Anyone has a better solution for this interoperability issue?