何时使用 extern“C”简单来说?

发布于 2024-08-31 19:58:05 字数 559 浏览 3 评论 0原文

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

extern "C" {

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

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

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

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

在 C++ 中编译但链接到已构建的 C 库或其他内容时是否必须使用它?

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

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?

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?

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?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

想念有你 2024-09-07 19:58:05

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

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

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

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

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.

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, bool is valid C++ but not valid C, while _Bool exists in C99, but is not available in 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>.

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

绝不服输 2024-09-07 19:58:05

其他答案是正确的,但完整的“样板”示例可能会有所帮助。在 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 ...
//

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

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_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++.

晨曦慕雪 2024-09-07 19:58:05

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

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.

安人多梦 2024-09-07 19:58:05

我使用“extern c”,以便 C# 可以读取我的 C++ 代码,而无需找出导出 C++ dll 函数时进行的额外名称修改。否则,我必须在 C# 端的函数入口点末尾添加额外的无意义(或者实际上是非英语)字符,以便正确访问 dll 中的 C++ 函数。

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.

许一世地老天荒 2024-09-07 19:58:05

extern "C" {} 块告诉 C++ 编译器使用 C 命名和调用约定。如果您不使用此选项,则在尝试在 C++ 项目中包含 C 库时将会出现链接器错误,因为 C++ 会破坏名称。我倾向于在所有 C 标头中使用它,以防它们在 C++ 项目中使用:

#ifdef __cplusplus
extern "C" {
#endif

/* My library header */

#ifdef __cplusplus
} // extern
#endif

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:

#ifdef __cplusplus
extern "C" {
#endif

/* My library header */

#ifdef __cplusplus
} // extern
#endif
偏爱你一生 2024-09-07 19:58:05

当您想在 C++ 编译器编译的代码中使用 C 调用约定时,您需要使用 extern "C"。造成这种情况的原因有两个:

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

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

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

通常,C 头文件中的声明用 括起来,

#ifdef __cplusplus
extern "C" {
#endif

[... C declarations ...]

#ifdef __cplusplus
}
#endif

使其可以在 C++ 中使用。

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:

  • 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, ...).

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.

Typically the declarations in a C header file are surrounded with

#ifdef __cplusplus
extern "C" {
#endif

[... C declarations ...]

#ifdef __cplusplus
}
#endif

to make it usable from C++.

酷炫老祖宗 2024-09-07 19:58:05

C++ 函数会受到名称修改的影响。这使得它们无法直接从 C 代码调用,除非使用 extern "C"

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文