让我们说我有一个看起来像这样的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”防护中。有没有一种方法可以添加一些可以反转“ extern C”防护的内容,以便使用C ++链接构建foo3。也许是这样的:
#ifdef __cplusplus
extern 'CPP' { /* re-enable C++ name-mangling/linkage */
foo3(vector<int> &v);
}
谢谢。
答案 0 :(得分:11)
如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标头本身的声明中。然后,您无需将#include
包装在主cpp文件中。
如:
/* 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
然后,无论使用C ++还是C语言,所有使用者都可以#include "c_header.h"
。