我有一个C ++数学库并在Rust中编写项目。由于不可能直接从Rust调用C ++,但是为了调用C是可能的,我决定用C ++编写一个标准的包装器到C中。
除了具有复杂参数的函数之外,一切都或多或少地起作用,其中虚部由于某种原因而丢失。下面我提供了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;
}
现在我们将其编译为
g++ -c -std=gnu++11 -o export_c++.o export_c++.cc
并汇编到库
ar rcs libexport_c++.a export_c++.o
我们将在 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;
}
编译main.c
gcc -o main -L. -lexport_c++ main.c
并运行
./main
产生
a = 1.000000 + I 1.000000
b = 1.000000 + I 0.000000
我使用macOS并使用
进行编译Apple LLVM version 8.1.0 (clang-802.0.42)
这两个问题也与这个问题有些相关 identifier "creal" is undefined - seen on Mac but not on Linux和 c++ and <complex.h> with <complex> in separate files
当然,作为一种解决方法,我可以将复杂参数拆分为两个double
,因为在任何情况下我都会将代码称为生锈。
顺便说一下,用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
产生预期结果
a = 1.000000 + I 1.000000
b = 1.000000 + I 1.000000
答案 0 :(得分:0)
再添加一个源文件:
<强> EXPORT_C ++的.h 强>
//
// c and c++
//
struct complex_proxy
{
double real;
double imaginary;
};
#ifdef __cplusplus
extern "C" {
#endif
struct complex_proxy proxy_foo(struct complex_proxy a);
#ifdef __cplusplus
}
#endif
//
// c++ only
//
#ifdef __cplusplus
#include <complex>
std::complex<double> foo(const std::complex<double> a);
#else
#include <complex.h>
double _Complex c_foo(const double _Complex a);
#endif
<强> EXPORT_C ++。CPP 强>
#include "export_c++.h"
std::complex<double> foo(const std::complex<double> a){
return a;
}
struct complex_proxy proxy_foo(struct complex_proxy a)
{
auto result = foo({a.real, a.imaginary});
return { result.real(), result.imag() };
}
<强> EXPORT_C ++。ç强>
#include "export_c++.h"
double _Complex c_foo(const double _Complex a)
{
struct complex_proxy a_proxy = { creal(a), cimag(a) };
struct complex_proxy result = proxy_foo(a_proxy);
return result.real + result.imaginary * I;
}