When to use extern “C” in simple words? [duplicate]

冷暖自知 提交于 2019-11-27 15:37:40

问题


This question already has an answer here:

  • What is the effect of extern “C” in C++? 13 answers

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?


回答1:


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.




回答2:


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




回答3:


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.




回答4:


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.




回答5:


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



回答6:


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




回答7:


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



来源:https://stackoverflow.com/questions/2796796/when-to-use-extern-c-in-simple-words

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!