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

别来无恙 提交于 2019-11-29 01:07:55
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.

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.

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

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.

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" {} 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

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

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

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