Usage analysis of extern "C"
Deep Exploration of the meaning of extern "C" in C + +
1. Introduction
The C + + language was originally created as "A better C", but this does not mean that C + + global variables and functions in C + + are compiled and connected in exactly the same way as C. As a language that wants to be compatible with C,
C + + retains some of the characteristics of a procedural language (known by the world as "object-oriented"), so it can define global variables and functions that are not part of any class. However, C + + is an object-oriented programming language
, in order to support the overloading of functions, C + + has a distinct difference in how the global function is treated.
2. Speaking from the standard header file
An enterprise has given the following interview questions:
Interview questions
Why do standard header files have a structure similar to the following?
#ifndef __incvxworksh
#define __incvxworksh
#ifdef __cplusplus
extern "C" {
#endif
/*...*/
#ifdef __cplusplus
}
#endif
#endif/* __incvxworksh */
Analysis
Obviously, the compiler macro "#ifndef __incvxworksh, #define __incvxworksh, #endif" in the header file prevents the header file from being repeatedly referenced.
So
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
What is the role of it? We will be in the following one by one lanes.
3. Deep disclosure of extern "C"
extern "C" contains a double meaning, literally: First, the object it modifies is "extern", and secondly, the target it modifies is "C". Let's take a detailed reading of this twofold meaning.
The function or variable defined by extern "C" is of type extern;
extern is a keyword that indicates the scope (visibility) of functions and global variables in the C/s + + language, which tells the compiler that its declared functions and variables can be used in this module or in other modules. Remember, the following statement:
extern int A;
is simply a declaration of a variable that is not defined in the variable a , not for a allocates memory space. Variable A can only be defined once in all modules as a global variable, or a connection error occurs.
Typically, the function and global variables that this module provides to other modules in the header file of the module are declared with the keyword extern . For example, if module B is to reference the global variables and functions defined in module A, only the header file of module A can be included. In this way, when a function in module A is called in Module B, in the compile phase, Module B cannot find the function, but it does not error; it will find this function in the target code generated from module A during the connection phase .
with the extern the corresponding keyword is Static , the global variables and functions that are modified by it can only be used in this module. Therefore, a function or variable may not be modified by extern "C" only if it is used by this module .
The variables and functions modified by extern "C" are compiled and concatenated in C language;
How to compile without extern "C" declaration
Let's start with a look at how C + + is compiled for a function that is similar to.
As an object-oriented language, C + + supports function overloading, whereas programming language C is not supported. Functions are compiled in C + + with different names in the symbol library than in the C language. For example, suppose a function is prototyped as:
void foo (int x, int y);
The function is compiled by the C compiler in the symbol library with the name _foo, while the C + + compiler produces names like _foo_int_int (different compilers may generate different names, but all use the same mechanism, and the resulting new name is called "Mangled Name").
_foo_int_int such a name includes the function name, function parameter number and type information, C + + is this mechanism to implement function overloading. For example, in C + +, the function void foo (int x, int y) is not the same as the symbol generated by the compilation of void foo (int x, float y), which is _foo_int_float.
Similarly, variables in C + + support class member variables and global variables in addition to local variables. The class member variable of the program that the user writes may have the same name as the global variable, and we use the "." to differentiate. In essence, the compiler, when compiling, is similar to the processing of the function and takes a unique name for the variable in the class, which differs from the name of the global variable named in the user program.
How to connect without extern "C" declaration
Assume that in C + +, the header file for module A is as follows:
Module a header file moduleA.h
#ifndef module_a_h
#define Module_a_h
int foo (int x, int y);
#endif
Reference the function in module B:
Module B implementation file ModuleB.cpp
#include "ModuleA.h"
Foo (2,3);
In fact, during the connection phase, the connector looks for symbols like _foo_int_int from the target file Modulea.obj generated by module A!
add extern "C" after the declaration of the compilation and connection mode
After adding the extern "C" declaration, the header file of module a becomes:
Module a header file moduleA.h
#ifndef module_a_h
#define Module_a_h
extern "C" int foo (int x, int y);
#endif
Foo (2,3) is still called in the implementation file of Module B, and the result is:
(1) When module A compiles the target code of Foo, it does not have special handling of its name and adopts the C language method;
(2) The connector is looking for an unmodified symbol name when looking for foo (2,3) call for the target code of module B _foo .
If the function in module a declares Foo to be an extern "C" type, and Module B contains an extern int foo (int x, int y), module B cannot find the function in module A, and vice versa.
Therefore, it is possible to summarize the true purpose of the extern "C" statement in one sentence (the birth of any grammatical feature in any language is not arbitrary and is driven by demand from the real world.) When we're thinking about a problem, we can't just stay in the language, ask why it's doing it, what the motive is, so we can understand a lot more in depth:
Implement mixed programming of C + + and C and other languages.
Understand the C + + in the establishment of the extern "C" motivation, we are below to specifically analyze the extern "C" the usual use of skills.
4.extern "C" idiomatic method
(1) in C + +, references to functions and variables in the C language, in the case of a C language header file (assuming cExample.h), the following processing is required:
extern "C"
{
#include "cExample.h"
}
and in C in the header file of a language, the external function can only be specified as extern type, C not supported in language extern "C" declaration, in . C the file contains extern "C" A compile syntax error occurs .
The author of C + + reference C Function Example project contains the source code of the three files as follows:
/* C Language header file: CExample.h */
#ifndef C_example_h
#define C_example_h
extern int Add (int x,int y); Note: written as extern "C" int add (int, int); can also
#endif
/* C language Implementation file: CEXAMPLE.C */
#include "cExample.h"
int add (int x, int y)
{
return x + y;
}
C + + implementation file, call Add:cppFile.cpp
extern "C"
{
#include "cExample.h"//NOTE: Here is inappropriate, if this compilation pass, instead, replaced by extern "C" int add (int, int); can be done by
}
int main (int argc, char* argv[])
{
Add (2,3);
return 0;
}
if C + + Call a C language written by . DLL when it is included . DLL or declare an interface function, you should add extern "C" {}.
( 2 ) in C referenced in C + + functions and variables in the language, C + + header file to be added extern "C" , but in C the declaration cannot be directly referenced in the language extern "C" The header file, you should only C file will C + + defined in the extern "C" function is declared as extern type.
The author of the C-referenced function example of the three files in the project contains the following source code:
C + + header file CppExample.h
#ifndef Cpp_example_h
#define Cpp_example_h
extern "C" int Add (int x, int y);
#endif
C + + implementation file CppExample.cpp
#include "cppExample.h"
int add (int x, int y)
{
return x + y;
}
/* C Implementation file cfile.c
/* This compiles an error: #include "cExample.h" */
extern int Add (int x, int y);
int main (int argc, char* argv[])
{
Add (2, 3);
return 0;
}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
extern "C" explanation