关于c ++:何时在简单的单词中使用extern“C”?

When to use extern “C” in simple words?

本问题已经有最佳答案,请猛点这里访问。

也许我不理解C和C++之间的区别,但是什么时候以及为什么我们需要使用

1
extern"C" {

?显然这是一个"联系公约"。

我简单地读了一下,注意到MSV中包含的所有.h头文件都用它包围了它们的代码。什么类型的代码恰好是"C代码"而不是"C++代码"?我认为C++包含了所有的C代码?

我猜这不是事实,C++是不同的,标准特征/函数存在于一个或另一个,但不是两者(即:Prttf是C和cOutt是C++),但是C++是向后兼容的,但是外部的"C"声明。这是正确的吗?

我的下一个问题取决于第一个问题的答案,但我还是会在这里问:因为用C编写的MSV头文件被外部"C"包围…},您何时需要自己在自己的代码中使用它?如果你的代码是C代码,而你试图在C++编译器中编译它,那么它应该不会有问题,因为你所包括的所有标准的H文件都已经有了C++的编译器中的"外部""C"的东西了吗?

在编译C++时必须使用它,但链接到已经构建的C库还是什么?


在声明在C.中实现/编译的函数时,您需要在C++中使用EDCOX1(0),使用EDCOX1(0)来告诉编译器/链接器使用C命名和调用约定,而不是使用C++名称处理和C++调用约定。对于其他库提供的函数,您几乎不需要使用EDCOX1(0)},而且写的库将已经存在于它向C和C++输出的公共API中。但是,如果您编写一个库,您希望在C和C++中都可用,那么您必须有条件地将其放入头文件中。

至于所有C代码是否是C++代码…不,那不正确。C++是"C的超集",这是一个流行的神话。虽然C++确实力求尽可能与C兼容,但也存在一些不兼容之处。例如,BoOL是有效的C++,但不是有效的C,而BuOL存在于C99中,但在C++中是不可用的。

至于是否需要在系统的.h文件中使用extern"c"…任何设计良好的实现都将在其中为您提供这些功能,这样您就不需要使用它们。但是,为了确保提供了它们,您应该包含以"c"开头并省略".h"的等效头文件。例如,如果包含< cType .h >,几乎任何合理的系统都会添加外部的"C";但是,要保证C++兼容的头,您应该包括头< ccType >。

您可能还感兴趣的是从C++ FAQ Lite中混合C和C++。


其他答案是正确的,但是一个完整的"样板"示例可能会有所帮助。C和/或C++项目中包含C代码的规范方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//
// C_library.h
//

#ifdef __cplusplus
extern"C" {
#endif

//
// ... prototypes for C_library go here ...
//

#ifdef __cplusplus
}
#endif

-

1
2
3
4
5
6
7
8
9
//
// C_library.c
//

#include"C_library.h"

//
// ... implementations for C_library go here ...
//

-

1
2
3
4
5
6
7
8
9
10
//
// C++_code.cpp
//

#include"C_library.h"
#include"C++_code.h"

//
// ... C++_code implementation here may call C functions in C_library.c ...
//

注意:上面也适用于从Objective-C++调用C代码。


C++编译器将它们的符号表中的名称与C编译器不同。您需要使用EDCOX1×0声明来告诉C++编译器在创建符号表时使用C约束规则来代替。


当你想在C++编译器编译的代码中使用C调用约定时,你需要使用EDCOX1 0。原因有两个:

  • 您在C中实现了一个函数,并希望从C++调用它。

  • 你有一个函数在C++中实现,并想从C调用它。注意,在这种情况下,你只能在函数接口中使用C++的C部分(没有类,…)。

除了C之外,这也适用于当您想在C++和其他语言之间进行互操作时,它们使用与C相同的调用和命名约定。

通常,C头文件中的声明被

1
2
3
4
5
6
7
8
9
#ifdef __cplusplus
extern"C" {
#endif

[... C declarations ...]

#ifdef __cplusplus
}
#endif

使它可以从C++中使用。


EDCOX1的5个块告诉C++编译器使用C命名和调用约定。如果你不使用这个,你会得到链接错误,如果试图包含C库与你的C++项目,因为C++会损坏名称。我倾向于在所有的C标题上使用它,以防万一在C++项目中使用。

1
2
3
4
5
6
7
8
9
#ifdef __cplusplus
extern"C" {
#endif

/* My library header */

#ifdef __cplusplus
} // extern
#endif

我使用"ExtEngC:C"来读取C++代码,而不必导出导出C++ DLL函数时所做的额外名称。否则,有额外的荒谬(或真正的,非英语)字符,我必须添加在C输入端的函数入口点的末尾,以便在DLL中正确访问C++函数。


C++函数是以名字命名的。这使得它们无法直接从C代码调用,除非使用extern"C"