首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有没有办法在使用外部'C‘后重新启用名称损坏?

有没有办法在使用外部'C‘后重新启用名称损坏?
EN

Stack Overflow用户
提问于 2018-08-10 15:31:56
回答 1查看 150关注 0票数 1

假设我有一个c++头文件,如下所示:

代码语言:javascript
复制
/* 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头文件中:

代码语言:javascript
复制
/* 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(),我这样做:

代码语言:javascript
复制
/* 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++链接构建。可能是这样的:

代码语言:javascript
复制
#ifdef __cplusplus
extern 'CPP' {  /* re-enable C++ name-mangling/linkage */
   foo3(vector<int> &v);
}

谢谢。

EN

回答 1

Stack Overflow用户

发布于 2018-08-10 15:41:23

正如在https://en.cppreference.com/w/cpp/language/language_linkage中所解释的,您可以同时使用extern "C"extern "C++" (后者是C++的缺省设置)。

它还说

当语言规范嵌套时,最里面的规范就是生效的规范。

所以

代码语言:javascript
复制
extern "C" {
    extern "C++" void foo3(vector<int> &v);
}

应该工作得很好。

也就是说,更好的解决方案是将#ifdef __cplusplus / extern "C" {部分添加到C标头本身的声明中。这样就不需要在主cpp文件中包装#include了。

如下所示:

代码语言:javascript
复制
/* 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中。

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51781302

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档