什么时候用简单的话使用 extern "C"?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2796796/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 00:43:30  来源:igfitidea点击:

When to use extern "C" in simple words?

c++cextern-c

提问by Russel

Maybe I'm not understanding the differences between C and C++, but when and why do we need to use

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

extern "C" {

? Apparently its a "linkage convention".

? 显然它是一个“链接约定”。

I read about it briefly and noticed that all the .h header files included with MSVS surround their code with it. What type of code exactly is "C code" and NOT "C++ code"? I thought C++ included all C code?

我简要地阅读了它,并注意到 MSVS 中包含的所有 .h 头文件都用它包围了它们的代码。究竟什么类型的代码是“C 代码”而不是“C++ 代码”?我认为 C++ 包含所有 C 代码?

I'm guessing that this is not the case and that C++ is different and that standard features/functions exist in one or the other but not both (ie: printf is C and cout is C++), but that C++ is backwards compatible though the extern "C" declaration. Is this correct?

我猜测情况并非如此,C++ 是不同的,标准特性/函数存在于一个或另一个中,但不是两者都存在(即:printf 是 C,cout 是 C++),但是 C++ 是向后兼容的,尽管外部“C”声明。这样对吗?

My next question depends on the answer to the first, but I'll ask it here anyway: Since MSVS header files that are written in C are surrounded by extern "C" { ... }, when would you ever need to use this yourself in your own code? If your code is C code and you are trying to compile it in a C++ compiler, shouldn't it work without problem because all the standard h files you include will already have the extern "C" thing in them with the C++ compiler?

我的下一个问题取决于第一个的答案,但无论如何我都会在这里问:由于用 C 编写的 MSVS 头文件被 extern "C" { ... } 包围,所以你什么时候需要使用它自己在自己的代码中?如果您的代码是 C 代码并且您正试图在 C++ 编译器中编译它,它是否应该可以正常工作,因为您包含的所有标准 h 文件都已经使用 C++ 编译器在其中包含了 extern "C" 内容?

Do you have to use this when compiling in C++ but linking to already built C libraries or something?

在用 C++ 编译但链接到已经构建的 C 库或其他东西时,您是否必须使用它?

回答by Michael Aaron Safyan

You need to use extern "C"in C++ when declaring a function that was implemented/compiled in C. The use of extern "C"tells the compiler/linker to use the C naming and calling conventions, instead of the C++ name mangling and C++ calling conventions that would be used otherwise. For functions provided by other libraries, you will almost never need to use extern "C", as well-written libraries will already have this in there for the public APIs that it exports to both C and C++. If, however, you write a library that you want to make available both in C and in C++, then you will have to conditionally put that in your headers.

extern "C"在声明在 C 中实现/编译的函数时,您需要在 C++ 中使用。 的使用extern "C"告诉编译器/链接器使用 C 命名和调用约定,而不是否则将使用的 C++ 名称修饰和 C++ 调用约定. 对于其他库提供的函数,您几乎永远不需要使用extern "C",因为编写良好的库已经为它导出到 C 和 C++ 的公共 API 提供了它。但是,如果您编写了一个要在 C 和 C++ 中都可用的库,那么您将不得不有条件地将它放在您的头文件中。

As for whether all C code is C++ code... no, that is not correct. It is a popular myth that C++ is a "superset of C". While C++ certainly strives to be as compatible with C as possible, there are some incompatibilities. For example, boolis valid C++ but not valid C, while _Boolexists in C99, but is not available in C++.

至于是否所有的 C 代码都是 C++ 代码……不,那是不正确的。C++ 是“C 的超集”是一个流行的神话。虽然 C++ 肯定会努力与 C 尽可能兼容,但也存在一些不兼容之处。例如,bool是有效的 C++,但不是有效的 C,而_Bool在 C99 中存在,但在 C++ 中不可用。

As to whether you will ever need to use extern "C" with the system's ".h" files.... any well-designed implementation will have those in there for you, so that you do not need to use them. However, to be certain that they are provided, you should include the equivalent header file that begins with "c" and omits ".h". For example, if you include <ctype.h>, almost any reasonable system will have the extern "C" added; however, to be assured a C++-compatible header, you should instead include the header <cctype>.

至于您是否需要将 extern "C" 与系统的 ".h" 文件一起使用……任何设计良好的实现都会为您提供这些文件,因此您不需要使用它们。但是,为了确定它们已提供,您应该包含以“c”开头并省略“.h”的等效头文件。例如,如果包含 <ctype.h>,几乎任何合理的系统都会添加 extern "C";但是,为了确保与 C++ 兼容的标头,您应该改为包含标头 <cctype>。

You may also be interested in Mixing C and C++ from the C++ FAQ Lite.

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

回答by Paul R

The other answers are correct, but a complete "boilerplate" example will probably help. The canonical method for including C code in C and/or C++ projects is as follows:

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

//
// C_library.h
//

#ifdef __cplusplus
extern "C" {
#endif

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

#ifdef __cplusplus
}
#endif

-

——

//
// C_library.c
//

#include "C_library.h"

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

-

——

//
// C++_code.cpp
//

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

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

Note: the above also applies to calling C code from Objective-C++.

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

回答by Ignacio Vazquez-Abrams

C++ compilers mangle the names in their symbol table differently than C compilers. You need to use the extern "C"declaration to tell the C++ compiler to use the C mangling convention instead when building the symbol table.

C++ 编译器对符号表中名称的处理与 C 编译器不同。您需要使用extern "C"声明来告诉 C++ 编译器在构建符号表时使用 C 重整约定。

回答by mmr

I use 'extern c' so that C# can read my C++ code without having to figure out the extra name mangling done when exporting a C++ dll function. Otherwise, there are extra nonsensical (or really, non-English) characters that I have to add at the end of a function entry point on the C# side in order to properly access a C++ function in a dll.

我使用“extern c”,以便 C# 可以读取我的 C++ 代码,而无需弄清楚在导出 C++ dll 函数时所做的额外名称修改。否则,为了正确访问 dll 中的 C++ 函数,我必须在 C# 端的函数入口点末尾添加额外的无意义(或真正的非英语)字符。

回答by Mike Weller

extern "C" {}blocks tell a C++ compiler to use the C naming and calling conventions. If you don't use this you will get linker errors if trying to include a C library with your C++ project because C++ will mangle the names. I tend to use this on all my C headers just in case they are ever used in a C++ project:

extern "C" {}块告诉 C++ 编译器使用 C 命名和调用约定。如果你不使用它,如果你试图在你的 C++ 项目中包含一个 C 库,你会得到链接器错误,因为 C++ 会破坏名称。我倾向于在我所有的 C 头文件上使用它,以防它们在 C++ 项目中使用过:

#ifdef __cplusplus
extern "C" {
#endif

/* My library header */

#ifdef __cplusplus
} // extern
#endif

回答by starblue

You need to use extern "C"when you want to use the C calling convention in code compiled by a C++ compiler. There are two reasons for this:

你需要使用extern "C"的时候要使用C调用代码约定由C ++编译器编译。有两个原因:

  • You have a function implemented in C and want to call it from C++.

  • You have a function implemented in C++ and want to call it from C. Note that in this case you can only use the C part of C++ in the function interface (no classes, ...).

  • 您有一个用 C 实现的函数,并想从 C++ 调用它。

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

Apart from C this also applies when you want to interoperate between C++ and other languages which use the same calling and naming conventions as C.

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

Typically the declarations in a C header file are surrounded with

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

#ifdef __cplusplus
extern "C" {
#endif

[... C declarations ...]

#ifdef __cplusplus
}
#endif

to make it usable from C++.

使其可从 C++ 使用。

回答by Nathan Osman

C++ functions are subject to name mangling. This makes them impossible to call directly from C code unless extern "C"is used.

C++ 函数受name mangling 的影响。这使得它们不可能直接从 C 代码调用,除非extern "C"使用。