Detailed explanation of the function of extern "C"

Posted by Jackdaw on Thu, 13 Jan 2022 04:04:21 +0100

The main function of extern "C" is to correctly implement C + + code and call other C language code. After adding extern "C", the compiler will be instructed to compile this part of the code in C language instead of C + +. Since C + + supports function overloading, the compiler will add the parameter type of the function to the compiled code during function compilation, not just the function name; C language does not support function overloading, so the function of C language code will not be compiled with the parameter type of the function, generally including the function name.

This function is very useful because before the emergence of C + +, many codes were written in C language, and the very bottom library was also written in C language. In order to better support the original C code and the written C language library, it is necessary to support C as much as possible in C + +, and extern "C" is one of the strategies.

This function is mainly used in the following situations:

  1. C + + code calls C language code
  2. Used in C + + header files
  3. In the collaborative development of multiple people, some people may be good at C language, while others are good at C + +, which will also be useful in this case

Take a simple example:

There are two modules, moduleA and moduleB. B calls the code in A, where A is implemented in C language and B is implemented in C + +. An implementation method is given below:

//moduleA header file
#ifndef __MODULE_A_H / / for module a, this macro is used to prevent repeated references to header files
#define __MODULE_A_H
int fun(int, int);
#endif
 
//moduleA implementation file C / / the implementation of module A remains unchanged
#include"moduleA"
int fun(int a, int b)
{
return a+b;
}
 
//moduleB header file
#idndef __MODULE_B_H / / obviously, this part is also to prevent repeated references
#define __MODULE_B_H
#ifdef __cplusplus / / this part tells the compiler if__ Cplusplus (that is, if it is a cpp file, external "C" {/ / because the cpp file defines the macro by default), it is compiled in C language
 
#include"moduleA.h"
#endif<br>
... //Other codes
 
#ifdef __cplusplus
}
#endif
#endif
 
//moduleB implementation file The implementation of CPP / / b module has not changed, but the design of header file has changed
#include"moduleB.h"<br>
int main()
{
  cout<<fun(2,3)<<endl;
}

Supplementary introduction:

Because C and C + + compilers do not compile functions exactly the same, especially for C + +, they support function overloading. Compiled functions are generally named after function name and formal parameter type.

For example, the compiled function void fun(int, int) may be_ fun_ int_ Int (different compilers may be different, but they all use a similar mechanism to name the compiled function name with function name and parameter type); C language does not have a similar overload mechanism. It usually uses the function name to indicate the compiled function name. The corresponding function above may be_ A name like fun.

Look at the following interview question: why do standard header files have similar structures?

#ifndef __ Incvxwork / * prevent the header file from being referenced repeatedly*/
#define __INCvxWorksh
#ifdef __cplusplus / / tells the compiler that this part of the code is compiled in C language format instead of C + +
extern "C"{
#endif
 
/*...*/
 
#ifdef __cplusplus
}
 
#endif
#endif /*end of __INCvxWorksh*/

analysis:

  • Obviously, the purpose of compiling macros "#ifndef _incvxwork, #define _incvxwork, #endif" in the header file is to prevent the header file from being referenced repeatedly
  • So what is the purpose of the following code?
#ifdef __cplusplus (where _cplusplus is a custom macro in cpp!!!)
extern "C"{
#endif
#ifdef __cplusplus
}
#endif

extern "C" has a double meaning. Literally, first of all, the target modified by it is "extern"; Secondly, the object code modified by it is "C".

  • The function or variable qualified by extern "C" is of type extern

extern is a keyword in C/C + + language that indicates the scope of functions and global variables. This keyword tells the compiler that the declared functions and variables can be used in this module or other modules.

Remember, the statement: extern int a; It is just a declaration of a variable, which does not define variable a or allocate space for a. Variable a can only be defined once in all modules as a global variable, otherwise an error will occur.

Generally speaking, in the header file of the module, the functions and global variables provided by the module to other modules for reference are given the keyword extern. For example, if module B wants to reference the global variables and functions defined in module a, it only needs to include the header file of module a. In module B, when calling function in module A, module B can not find this function in compile phase, but it will not report error. It will find the function in the object code compiled by module a during the link phase.

The keyword corresponding to extern is static. Static indicates that variables or functions can only be used in this module. Therefore, variables or functions modified by static cannot be modified by extern C.

  • Variables and functions modified by extern "C" are compiled and linked in C language: This is very important!!!!

As mentioned above, since C + + supports function overloading, but C language does not, the name of the function in the symbol library after being compiled by C + + is different from that in C language; The function compiled by C + + needs to add the type of parameter to uniquely calibrate the overloaded function. After adding extern "C", it is to indicate to the compiler that this code is compiled in the way of C language

Link method without extern "C" Declaration:

//Module A header file ModuleA h
#idndef _MODULE_A_H
#define _MODULE_A_H
 
int foo(int x, int y);
#endif 

Call this function in module B:

//Module B implementation file cpp
#include"moduleA.h"
foo(2,3);

In fact, during the linking phase, the linker generates the target file ModuleA from module A Found in obj_ foo_int_int, which is obviously impossible to find, because the foo() function is compiled into_ Foo symbol, so A link error occurs.

For common practices, refer to the following implementation (moduleA and moduleB. B calls the code in A, where A is implemented in C language and B is implemented in C + +):

//moduleA header file
#ifndef __MODULE_A_H / / for module a, this macro is used to prevent repeated references to header files
#define __MODULE_A_H
int fun(int, int);
#endif
 
//moduleA implementation file C / / the implementation of module A remains unchanged
#include"moduleA"
 
int fun(int a, int b)
{
    return a+b;
}
 
//moduleB header file
#idndef __MODULE_B_H / / obviously, this part is also to prevent repeated references
#define __MODULE_B_H
 
#ifdef __cplusplus / / this part tells the compiler if__ Cplusplus (that is, if it is a cpp file, external "C" {/ / because the cpp file defines the macro by default), it is compiled in C language
 
#include"moduleA.h"
#endif
 
... //Other codes
 
#ifdef __cplusplus
}
#endif
#endif
 
//moduleB implementation file The implementation of CPP / / b module has not changed, but the design of header file has changed
#include"moduleB.h"
int main()
{
    cout<<fun(2,3)<<endl;
}

Summary of use points of extern "C"

  • It can be a single statement as follows
extern "C" double sqrt(double);
  • It can be a compound statement, which is equivalent to adding extern "C" to the declarations in the compound statement
extern "C"
{
      double sqrt(double);
      int min(int, int);
}

  • You can include header files, which is equivalent to adding extern "C" to all declarations in the header file
extern "C"
{
    #i nclude <cmath>
} 
  • extern "C" cannot be added inside a function
  • If a function has multiple declarations, it can all be added with extern "C", or it can only appear in the first declaration, and the subsequent declarations will accept the rule of the first link indicator.
  • In addition to extern "C", there are extern "FORTRAN" and so on.

Reference article:

extern C use

Function of extern c [turn]_ Look at the snow

Key points for using extern C

http://blog.chinaunix.net/u/29619/showart_230148.html

extern "C" function control yourself. - CSDN blog

Ruliu, a new generation of intelligent working platform

Transferred from: Detailed explanation of the role of extern "C" - xiaojinwu will shine - Z & M - blog Park (cnblogs.com)

Topics: C C++ Back-end