有没有办法在使用extern'C'后重新启用名称修改?

GHe*_*GHe 2 c 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
Run Code Online (Sandbox Code Playgroud)

现在我将此头文件包含在C头文件中:

/* c_header.h - all implementation built with C compiler */
#include <stdio.h>
#include "cpp_header.h"

int cfoo();
int cfoo1(int x);
Run Code Online (Sandbox Code Playgroud)

现在让我说我想在另一个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;
}
Run Code Online (Sandbox Code Playgroud)

上面的代码永远不会构建,因为第一个头文件中的'foo3()'会抱怨我们正在尝试使用C-linkage构建模板.发生这种情况是因为我们将整个c_header.h文件包装在'extern C'防护中.有没有办法可以添加一些可以反转'extern C'保护的东西,这样就可以用C++链接构建foo3.也许是这样的:

#ifdef __cplusplus
extern 'CPP' {  /* re-enable C++ name-mangling/linkage */
   foo3(vector<int> &v);
}
Run Code Online (Sandbox Code Playgroud)

谢谢.

mel*_*ene 11

https://en.cppreference.com/w/cpp/language/language_linkage中所述,您可以同时使用extern "C"extern "C++"(后者是C++的默认设置).

它还说

当语言规范嵌套时,最内层的规范是有效的规范.

所以

extern "C" {
    extern "C++" void foo3(vector<int> &v);
}
Run Code Online (Sandbox Code Playgroud)

应该工作正常.

也就是说,更好的解决方案是将#ifdef __cplusplus/ extern "C" {parts 添加到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
Run Code Online (Sandbox Code Playgroud)

然后所有消费者都可以#include "c_header.h",无论他们是在C++还是C.