在外部"C" { }
中仍定义了宏__cplusplus
。当我想在动态加载的库头中包含mpi.h
的C版本时,这将无法工作,因为mpi.h
仍会找到__cplusplus
并仍会像由...打开一样加载C ++。
#undef __cplusplus
与gcc一起使用。但是我不想依靠这个。
那么如何编写一个C ++程序
-使用cpi版本的mpi和
-链接到使用mpi C版本的C库(其中#include <mpi.h>
已经出现在标题中了?
示例代码:
library.h:
#ifdef __cplusplus
extern "C" {
#endif
#include <mpi.h>
void library_do(MPI_Comm comm);
#ifdef __cplusplus
}
#endif
program.cpp:
#include <library.h>
#include <mpi.h>
int main() {
MPI::Init();
// do some mpi C++ calls...
library_do(MPI::COMM_WORLD);
MPI::Finalize();
}
如果有人想在此处播放示例库。c:
#include <stdio.h>
#include "library.h"
void library_do(MPI_Comm comm)
{
int rank;
MPI_Comm_rank(comm, &rank);
printf("MPI Rank: %d", rank);
}
并编译我尝试的所有内容
mpicc -shared library.c -o lib.so
mpicxx program.cpp -l lib.so
答案 0 :(得分:6)
__cplusplus
将始终由编译器定义。 extern "C" {}
只为您提供C链接,因此其中的代码可与C编译器很好地配合。
答案 1 :(得分:3)
因为它们是不同的东西。 extern "C" {}
告诉编译器如何导出符号(see here),而__cplusplus
告诉您可以使用C ++代码,以便您的库可以在#ifdef
之间使用不同的代码路径。
答案 2 :(得分:3)
使用重点
#ifdef __cplusplus
extern "C" {
#endif
...
#ifdef __cplusplus
}
#endif
是为了防止C ++修改名称。基本上,我们说的是不要像传统的C ++函数调用那样使用名称修饰,而是不要修饰它。 此链接可能很有用Name mangling
它用于使C头与C ++兼容。
标志__cplusplus
是在C ++编译器中自动定义的。
答案 3 :(得分:2)
当然是定义好的。仍然是在extern "C"
块内编译代码的C ++编译器。它不会停止将代码视为C ++,仅确保使用C调用/命名约定。
如果标头不能由C ++编译器编译,则唯一的办法是创建一个公开C ++兼容API的 C 包装器。
答案 4 :(得分:2)
编译器输出以下内容:
In file included from /usr/include/c++/4.8.2/bits/stl_algobase.h:61:0,
from /usr/include/c++/4.8.2/bits/stl_tree.h:61,
from /usr/include/c++/4.8.2/map:60,
from /usr/include/openmpi-x86_64/openmpi/ompi/mpi/cxx/mpicxx.h:38,
from /usr/include/openmpi-x86_64/mpi.h:2674,
from x1.cpp:6:
/usr/include/c++/4.8.2/bits/cpp_type_traits.h:72:3: error: template with C linkage
template<typename _Iterator, typename _Container>
^
/usr/include/c++/4.8.2/bits/cpp_type_traits.h:85:3: error: template with C linkage
template<bool>
^
...
mpi.h标头检测到它正在被编译为C ++,因此包含C ++特定的功能。但是,模板(除其他外)不适用于C链接(例如,标头在extern "C"
块内)。
移动包含在extern "C"
上方的包含内容:
#include <mpi.h>
#ifdef __cplusplus
extern "C" {
#endif
void library_do(MPI_Comm comm);
#ifdef __cplusplus
}
#endif
答案 5 :(得分:1)
如果您使用C ++程序#include <mpi.h>
,请不要在其中使用extern "C"
。至少OpenMPI和Intel MPI在标头本身中为您执行此操作-如果定义了__cplusplus
。
您可能会遇到麻烦,因为某些MPI实现仍在mpi.h
中定义了已从标准中删除的C ++接口。这显然在extern "C"
下失效。例如,对于OpenMP,您可以通过设置OMPI_SKIP_MPICXX
来跳过。这样,双extern "C"
就可以了,但是我还是不推荐。
更新:如果您无法修改库头,请在#include <mpi.h>
之前#include <lib.h>
。
也就是说,您不应将C ++绑定用于MPI。三年后,将它们从标准中删除。