I have a C++ mathematical library and writing a project in Rust. Since it is not possible to call C++ directly from Rust, but to call C is possible, I decided to write a standard wrapper from C++ into C.
Everything is working more or less as expected except of functions which have complex parameters, where the imaginary part is lost for some reason. Below I provide mwe.
export_c++.h
#ifdef __cplusplus
#include <complex>
std::complex<double> foo(const std::complex<double> a);
#endif
#ifdef __cplusplus
extern "C" {
#endif
#include <complex.h>
double _Complex c_foo(const double _Complex a);
#ifdef __cplusplus
}
#endif
export_c++.cc
#include "export_c++.h"
#include <iostream>
std::complex<double> foo(const std::complex<double> a){
return a;
}
double _Complex c_foo(const double _Complex a){
std::complex<double> b{a};
double _Complex res{b.real(), b.imag()};
return res;
}
now we compile this as
g++ -c -std=gnu++11 -o export_c++.o export_c++.cc
and assemble into library
ar rcs libexport_c++.a export_c++.o
and we will use it in main.c
#include "export_c++.h"
#include <stdio.h>
int main(int argc, char *argv[])
{
double complex a = 1. + I * 1.;
double complex b = c_foo(a);
printf("a = %f + I %f\n", creal(a), cimag(a));
printf("b = %f + I %f\n", creal(b), cimag(b));
return 0;
}
Compile main.c
gcc -o main -L. -lexport_c++ main.c
and run
./main
which yields
a = 1.000000 + I 1.000000
b = 1.000000 + I 0.000000
I use macOS and compile with
Apple LLVM version 8.1.0 (clang-802.0.42)
Also these two questions are somewhat relevant to the question identifier "creal" is undefined - seen on Mac but not on Linux and c++ and <complex.h> with <complex> in separate files
Of course, as a workaround I can split the complex parameters into two double ones, since in any case I would call the code out of rust.
By the way, compilation with gcc 7.1.0
g++-7 -c -std=gnu++11 -o export_c++.o export_c++.cc
ar rcs libexport_c++.a export_c++.o
gcc-7 -o main -L. -lexport_c++ -lstdc++ main.c
produces expected result
a = 1.000000 + I 1.000000
b = 1.000000 + I 1.000000