假设我有一个c++头文件,如下所示:
/* cpp_header.h */
#include <vector>
#ifdef __cplusplus
extern 'C' {
#endif
void foo1(int x);
void foo2(int y);
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
/* function I don't want visible to C compiler */
void foo3(vector<int> &v);
#endif现在我将这个头文件包含到一个C头文件中:
/* c_header.h - all implementation built with C compiler */
#include <stdio.h>
#include "cpp_header.h"
int cfoo();
int cfoo1(int x);现在假设我想在另一个cpp文件中使用cfoo()和cfoo1(),我这样做:
/* crazy.cpp - this will cause a build breakage */
extern 'C' {
#include "c_header.h"
}
#include <iostream>
int main() {
cfoo();
cfoo1(88);
std::cout << "Yes, this is crazy!" << std::endl;
return 0;
}上面的代码永远不会构建,因为第一个头文件中的'foo3()‘会抱怨我们正在尝试构建一个带有C链接的模板。这是因为我们将整个c_header.h文件包装在一个“外部C”保护中。有没有一种方法可以添加一些东西来反转“外部C”保护,这样foo3就可以用C++链接构建。可能是这样的:
#ifdef __cplusplus
extern 'CPP' { /* re-enable C++ name-mangling/linkage */
foo3(vector<int> &v);
}谢谢。
发布于 2018-08-10 15:41:23
正如在https://en.cppreference.com/w/cpp/language/language_linkage中所解释的,您可以同时使用extern "C"和extern "C++" (后者是C++的缺省设置)。
它还说
当语言规范嵌套时,最里面的规范就是生效的规范。
所以
extern "C" {
extern "C++" void foo3(vector<int> &v);
}应该工作得很好。
也就是说,更好的解决方案是将#ifdef __cplusplus / extern "C" {部分添加到C标头本身的声明中。这样就不需要在主cpp文件中包装#include了。
如下所示:
/* c_header.h - all implementation built with C compiler */
#include <stdio.h>
#include "cpp_header.h"
#ifdef __cplusplus
extern "C" {
#endif
int cfoo();
int cfoo1(int x);
#ifdef __cplusplus
}
#endif然后,所有的消费者都可以只使用#include "c_header.h",无论他们是在C++中还是在C中。
https://stackoverflow.com/questions/51781302
复制相似问题