c++ - 从 C 代码调用具有复杂参数和复杂返回类型的 C++ 函数

标签 c++ c macos

我有一个 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

我们将在ma​​in.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 Linuxc++ and <complex.h> with <complex> in separate files

当然,作为一种解决方法,我可以将复杂的参数拆分为两个 double 参数,因为在任何情况下我都会调用代码 out of rust。

顺便用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

最佳答案

再添加一个源文件:

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++.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;
}

关于c++ - 从 C 代码调用具有复杂参数和复杂返回类型的 C++ 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44056901/

相关文章:

c++ - 异常允许我们分离什么?

c - 将各种txt文件读入c编程,将其保存到数组中并得出结论: Homework

java - 使用 Eclipse(或其他软件)进行远程 Java 开发?

xcode - 我如何验证死代码是否已从二进制文件中删除?

macos - OSX 修复 Selenium Chromedriver 启动错误产生未知系统错误 -86 可执行文件中的 CPU 类型错误?

c++ - 如何在Opencv中访问单 channel IplImage的元素

c++ - 以 cv::Point 为键的 std::map

c++ - 排列网格大小和 block 大小

c - 在 WM_MOUSEMOVE 中绘图

c - 下面的代码到底发生了什么