c++ - 有没有办法在使用 extern 'C' 后重新启用名称修改?
问题描述
假设我有一个如下所示的 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-linkage 构建模板。发生这种情况是因为我们将整个 c_header.h 文件包装在“extern C”保护中。有没有办法可以添加一些可以反转“extern C”保护的东西,以便 foo3 将使用 C++ 链接构建。也许是这样的:
#ifdef __cplusplus
extern 'CPP' { /* re-enable C++ name-mangling/linkage */
foo3(vector<int> &v);
}
谢谢。
解决方案
如https://en.cppreference.com/w/cpp/language/language_linkage中所述,您可以同时使用extern "C"
and 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
然后所有消费者都可以#include "c_header.h"
,无论他们是使用 C++ 还是 C。
推荐阅读
- javascript - 在firebase auth中将用户设为null
- swift - apple-app-site-association 文件是否适用于 GitHub Pages(即 site.github.io)?
- reactjs - 为什么我的日历小部件不允许我选择原始开始日之后的天数?
- python - turtle.Screen().screensize() 没有输出正确的屏幕尺寸
- c++ - 将地址分配给本地指针后,公共对象的变量消失
- javascript - Redux reducer 不显示我的控制台日志并返回 undefined
- php - 如何从 XML 中隐藏特定元素?
- javascript - 错误 [object Object] - 通过 File API 上传 Firebase 存储文件
- excel - 用大写字母更改单词的颜色
- python - 列表到字典:有重复的元素将充当键,但我想针对同一个键收集值并将其转换为列表值