2017-05-18 1 views
4

저는 C++ 수학 라이브러리가 있고 녹에 프로젝트를 작성했습니다. Rust에서 C++을 직접 호출 할 수는 없지만 C를 호출 할 수 있으므로 C++의 표준 래퍼를 C에 작성하기로 결정했습니다.C 코드에서 복소수 매개 변수와 복소수 반환 유형이있는 C++ 함수를 호출하십시오.

복잡한 매개 변수가있는 함수를 제외하면 모든 것이 예상대로 작동합니다 어떤 이유로 가상 부분이 손실됩니다. 아래에 나는 mwe를 제공합니다.

export_C++

#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 

으로이 컴파일 및 라이브러리

로 조립 617,451,515,
ar rcs libexport_c++.a export_c++.o 

우리는

gcc -o main -L. -lexport_c++ main.c 

,536,913,632을 산출하는

./main 

실행 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에서 사용합니다 10

a = 1.000000 + I 1.000000 
b = 1.000000 + I 0.000000 

나는 복잡한 매개 변수를 분할 할 수 있습니다 해결 방법으로, 맥 OS를 사용하고

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 개로 나눌 수 있습니다. 어떤 경우이든 코드를 녹슬지 않게 호출 할 것이기 때문입니다. . 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 
+1

IIRC에서는 IIRC를 사용하면 C++에서'_Complex'를 사용할 수 없습니다. 그들은 단지 C 다. [연결된 질문에 대한 답변 중 하나] (http://stackoverflow.com/a/31800404/1896169)에 이렇게 나와 있습니다. – Justin

답변

0

하나 이상의 소스 파일을 추가 예상이 생성 ++

export_c을 시간

// 
// 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++

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

C++ (소스) 파일의'struct complex_proxy' ('complex_proxy' 대신)를 타입으로 사용 하시겠습니까? 머리글과 대칭을 이루는 것 같습니다. –

+0

@DanielJour 먼저 헤더를 쓴 다음 cpp 파일에 잘라내거나 붙여 넣습니다. 하지만 당신 말이 맞아요, 이것이 C 함수의 구현이라는 단서를 제공합니다. –

+0

감사합니다. 그것은 작동합니다. 그러나 gcc가 아닌 clang에서 복잡한 숫자의 문제가 왜 발생하는지 이해하는 것도 좋습니다. 그것은 gcc의 일부 문서화되지 않은 기능입니까? – tupos