使用C++11和C库一起处理复数

3

我希望在我的应用程序中使用一个C库和一个C++11库。似乎C和C++11库中“complex”的用法冲突,并且会导致编译错误。下面是一个最小可行示例(MWE)。

myLib_C.h文件内容如下:

#ifndef MYLIBC_H
#define MYLIBC_H
#include <math.h>
#include <complex.h>
#ifdef  __cplusplus
extern "C" {
#endif
typedef float complex cfloat;
typedef double complex cdouble;
#define myFunc_cfloat(r,i) ((float)(r) + ((float)(i))*I)
#define myFunc_cdouble(r,i) ((double)(r) + ((double)(i))*I)
#ifdef __cplusplus
} // extern "C"
#endif
#endif

myLib_CPP.h文件的内容:

#ifndef MYLIBCPP_H
#define MYLIBCPP_H

#include "myLib_C.h" //uses myLib_C somewhere in this file
#include <iostream>
#include <complex>
inline void CppFunction()
{
    std::cout<<"This file need to be compiled using C++11\n";
    std::complex<float> a(10,100);
    std::complex<float> b(1, 1);
    auto c = a+b;
    std::cout<<"c= "<<c<<std::endl;
}

#endif // MYLIBCPP_H

我的main.cpp文件:

#include "myLib_C.h"
#include "myLib_CPP.h"
#include <iostream>
#include <complex>
int main()
{
    std::cout<<"Hello World\n";
    CppFunction();
    return 0;
}

CMakeLists.txt的内容:
cmake_minimum_required(VERSION 3.10)
project(myTest)
set(CMAKE_CXX_FLAGS "-std=c++11")
add_executable(myTest main.cpp)

当我编译时,出现以下错误:

error: expected initializer before ‘cfloat’
     typedef float complex cfloat;

一个类似的问题在C++中的复数对C语言的影响?中讨论。那里提到的解决方案是用_Complex替换complex。但我无法编辑C和C++库,所以这不适用于我的情况。


1
typedef float complex cfloat; 不是有效的 C++ 代码,无论是否使用 extern "C" 包围。您不能在任何 C++ 源文件中使用该 C 语法。为什么您认为需要这样做呢?所示代码包括 myLib_C.h,但没有明显的原因 - 您没有尝试使用其中的任何内容。 - Igor Tandetnik
extern "C" 是反向使用的。每当您想在 C 中使用 C++ 函数时,您需要将它们包装在 extern "C" 中。这样,C++ 就不会混淆支持函数重载所需的函数名称。 - mangupt
1个回答

5

extern "C" { ... } 并不能自动将大括号内的 C 代码转换成有效的 C++ 代码,因此这种方式不可行。

两种语言标准都要求它们各自的复数类型具有与相应浮点类型的两个数字数组相同的布局(即,无论是 C++ 的 std::complex<float> 还是 C 的 float complex 都表现得像 float[2],在布局上相同)。您可以利用这一点。例如:

#ifdef  __cplusplus
   using cfloat = std::complex<float>;
#else
   typedef float complex cfloat;
#endif

现在你可以在一种语言中声明变量,并将其传递到另一种语言中,这应该可以正常工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接