混合C / C ++标头可以包含另一个混合标头吗?

时间:2022-09-01 19:25:16

After reading Why do we need extern "C"{ #include <foo.h> } in C++? I concluded, including a header within the extern "C"-block is fine.

阅读之后为什么我们需要在C ++中使用extern“C”{#include }?我总结道,包括extern“C”-block中的标题很好。

But I ran into problems with this constellation:

但我遇到了这个星座的问题:

#ifdef __cplusplus
extern "C" {
#endif

#include "mixedstuff.h"

#ifdef __cplusplus
}
#endif

mixedstuff.h:

#ifdef __cplusplus
extern "C" {
#endif

#include "cstuff.h"

#ifdef __cplusplus
}
#include "cppstuff.h"
#endif

As one can see, I ended up with cppstuff.h being included by the C++ compiler within the extern "C" block. This caused a lot of errors, because many statements were just not possible with C-linkage.

可以看出,我最终将cppstuff.h包含在外部“C”块中的C ++编译器中。这导致了很多错误,因为很多语句都不可能与C-linkage相关。

The obvious solution is to #include mixedstuff.h outside the extern "C" block. But this requires me to look into each header to see if it is plain C, C++ or mixed.

显而易见的解决方案是在extern“C”块之外#include mixedstuff.h。但是这需要我查看每个标题,看看它是纯C,C ++还是混合。

From this I would recommend to make headers C++ aware, rather than including them in extern "C". Am I right, or is there a better way?

从这里我建议使标题C ++知道,而不是将它们包含在extern“C”中。我是对的,还是有更好的方法?

4 个解决方案

#1


2  

From your description, I gather that mixedstuff.h is designed to be used in both C and C++. Which means that it probably has #ifdef __cplusplus etc., with some pure C++ code in places. In such cases, it should not be included inside an extern "C" block. In general, unless explicitly documented otherwise, most headers should be included at the outermost level, outside all blocks, namespaces, etc. The one exception is pure C headers, where the author has not designed the library to be used from C++; those must be included within an extern "C" block. (But from what I've seen, such headers are becoing rarer and rarer.)

根据您的描述,我认为mixedstuff.h旨在用于C和C ++。这意味着它可能有#ifdef __cplusplus等,并且在某些地方使用了一些纯C ++代码。在这种情况下,它不应包含在extern“C”块中。通常,除非另有明确说明,否则大多数标题应包含在最外层,所有块,名称空间等之外。一个例外是纯C头,其中作者没有设计要从C ++使用的库;那些必须包含在外部“C”块中。 (但从我所看到的情况来看,这样的标题更为罕见和罕见。)

And you shouldn't have to look inside the headers; you need to look at the documentation.

你不应该看看标题内部;你需要查看文档。

And if you are the author of the header, then you should make it C++ aware (and document this fact, perhaps at the library level).

如果你是标题的作者,那么你应该让它知道C ++(并记录这个事实,也许是在图书馆一级)。

#2


1  

When the example tells you to put extern "C" in yourself, that is when you are including a C-only header.

当示例告诉您将extern“C”放在自己中时,就是当您包含一个只有C的标头时。

As it is C-only, it has been possibly written in C for C and so if you want to use it for C++, you need to specify it to being a C header.

因为它只是C语言,所以它可能用C语言编写,因此如果要将它用于C ++,则需要将其指定为C头。

IF you have mixstuff.h it won't work in C as it has C++ only constructs. Those that are C constructs that you want to have with C linkage you should mark explicitly within mixstuff.h. Or isolate them out into their own header.

如果你有mixstuff.h它将无法在C中工作,因为它只有C ++构造。那些你想要与C链接一起使用的C构造你应该在mixstuff.h中明确标记。或者将它们隔离到自己的标题中。

Note that together with mixstuff.h there will somewhere be a mixstuff.c or mixstuff.cpp being compiled or possibly even two different compilation units. You can us a C++ compiler to compile the implementations, and they can even be C++ (with C linkage) using in their implementations C++ constructs (and often are. You will often give your C++ library a C interface).

请注意,与mixstuff.h一起使用的是mixstuff.c或mixstuff.cpp正在编译或甚至可能是两个不同的编译单元。您可以使用C ++编译器来编译实现,它们甚至可以是C ++(使用C链接)在其实现C ++构造中使用(通常是。您经常会为C ++库提供C接口)。

If mixstuff was build in C++ originally with C++ name mangling it will not link with your code if you now put extern "C" around its declarations. If the functions really were built by a C compiler though, you need to use extern "C" so you can see them.

如果mixstuff是用C ++构建的,最初使用C ++名称修改它,如果你现在在其声明周围放置extern“C”,它将不会与你的代码链接。如果这些函数确实是由C编译器构建的,那么你需要使用extern“C”,这样你才能看到它们。

#3


1  

There are various C and C++ standards, which have commonalities and differences.

有各种C和C ++标准,它们有共性和差异。

If code is written in the common intersection of all your target-standards, just include it in the global namespace.

如果代码是在所有目标标准的公共交集中编写的,那么只需将其包含在全局命名空间中即可。

If it only misses extern "C" when included in C++, wrap it externally.

如果它只包含在C ++中时错过extern“C”,则将其包装在外部。

Otherwise, things get complicated, and you have to patch it directly.

否则,事情变得复杂,你必须直接修补它。

The preprocessor, with conditions on __cplusplus, __STDC_VERSION__ and other feature- and language-test macros, is a way to write code which behaves properly under a wider set of conditions than guaranteed by the general language itself.

具有__cplusplus,__ STDC_VERSION__和其他特征和语言测试宏条件的预处理器是一种编写代码的方法,这些代码在比一般语言本身保证的更广泛条件下正常运行。

Use it wisely, it is easy to misuse.

明智地使用它,很容易被滥用。

#4


1  

If you want to ensure stuff has C++ linkage even though the containing header file might be included inside an extern "C" block, you can use an extern "C++" block:

如果你想确保东西有C ++链接,即使包含的头文件可能包含在extern“C”块中,你可以使用extern“C ++”块:

extern "C++" {
#include "cppstuff.h"
}

#1


2  

From your description, I gather that mixedstuff.h is designed to be used in both C and C++. Which means that it probably has #ifdef __cplusplus etc., with some pure C++ code in places. In such cases, it should not be included inside an extern "C" block. In general, unless explicitly documented otherwise, most headers should be included at the outermost level, outside all blocks, namespaces, etc. The one exception is pure C headers, where the author has not designed the library to be used from C++; those must be included within an extern "C" block. (But from what I've seen, such headers are becoing rarer and rarer.)

根据您的描述,我认为mixedstuff.h旨在用于C和C ++。这意味着它可能有#ifdef __cplusplus等,并且在某些地方使用了一些纯C ++代码。在这种情况下,它不应包含在extern“C”块中。通常,除非另有明确说明,否则大多数标题应包含在最外层,所有块,名称空间等之外。一个例外是纯C头,其中作者没有设计要从C ++使用的库;那些必须包含在外部“C”块中。 (但从我所看到的情况来看,这样的标题更为罕见和罕见。)

And you shouldn't have to look inside the headers; you need to look at the documentation.

你不应该看看标题内部;你需要查看文档。

And if you are the author of the header, then you should make it C++ aware (and document this fact, perhaps at the library level).

如果你是标题的作者,那么你应该让它知道C ++(并记录这个事实,也许是在图书馆一级)。

#2


1  

When the example tells you to put extern "C" in yourself, that is when you are including a C-only header.

当示例告诉您将extern“C”放在自己中时,就是当您包含一个只有C的标头时。

As it is C-only, it has been possibly written in C for C and so if you want to use it for C++, you need to specify it to being a C header.

因为它只是C语言,所以它可能用C语言编写,因此如果要将它用于C ++,则需要将其指定为C头。

IF you have mixstuff.h it won't work in C as it has C++ only constructs. Those that are C constructs that you want to have with C linkage you should mark explicitly within mixstuff.h. Or isolate them out into their own header.

如果你有mixstuff.h它将无法在C中工作,因为它只有C ++构造。那些你想要与C链接一起使用的C构造你应该在mixstuff.h中明确标记。或者将它们隔离到自己的标题中。

Note that together with mixstuff.h there will somewhere be a mixstuff.c or mixstuff.cpp being compiled or possibly even two different compilation units. You can us a C++ compiler to compile the implementations, and they can even be C++ (with C linkage) using in their implementations C++ constructs (and often are. You will often give your C++ library a C interface).

请注意,与mixstuff.h一起使用的是mixstuff.c或mixstuff.cpp正在编译或甚至可能是两个不同的编译单元。您可以使用C ++编译器来编译实现,它们甚至可以是C ++(使用C链接)在其实现C ++构造中使用(通常是。您经常会为C ++库提供C接口)。

If mixstuff was build in C++ originally with C++ name mangling it will not link with your code if you now put extern "C" around its declarations. If the functions really were built by a C compiler though, you need to use extern "C" so you can see them.

如果mixstuff是用C ++构建的,最初使用C ++名称修改它,如果你现在在其声明周围放置extern“C”,它将不会与你的代码链接。如果这些函数确实是由C编译器构建的,那么你需要使用extern“C”,这样你才能看到它们。

#3


1  

There are various C and C++ standards, which have commonalities and differences.

有各种C和C ++标准,它们有共性和差异。

If code is written in the common intersection of all your target-standards, just include it in the global namespace.

如果代码是在所有目标标准的公共交集中编写的,那么只需将其包含在全局命名空间中即可。

If it only misses extern "C" when included in C++, wrap it externally.

如果它只包含在C ++中时错过extern“C”,则将其包装在外部。

Otherwise, things get complicated, and you have to patch it directly.

否则,事情变得复杂,你必须直接修补它。

The preprocessor, with conditions on __cplusplus, __STDC_VERSION__ and other feature- and language-test macros, is a way to write code which behaves properly under a wider set of conditions than guaranteed by the general language itself.

具有__cplusplus,__ STDC_VERSION__和其他特征和语言测试宏条件的预处理器是一种编写代码的方法,这些代码在比一般语言本身保证的更广泛条件下正常运行。

Use it wisely, it is easy to misuse.

明智地使用它,很容易被滥用。

#4


1  

If you want to ensure stuff has C++ linkage even though the containing header file might be included inside an extern "C" block, you can use an extern "C++" block:

如果你想确保东西有C ++链接,即使包含的头文件可能包含在extern“C”块中,你可以使用extern“C ++”块:

extern "C++" {
#include "cppstuff.h"
}