繁体   English   中英

使用C代码中的复杂参数和复杂返回类型调用C ++函数

[英]Call C++ function with complex parameters and complex return type out of C code

我有一个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 ++。立方厘米

#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)

这两个问题也与问题标识符“creal”有些相关- 未定义 - 在Mac上看到但在Linuxc ++ 上没有, 而<complex.h>在单独的文件中有<complex>

当然,作为一种解决方法,我可以将复杂的参数分成两个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

再添加一个源文件:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM