Deep exploration of the meaning of C++ – extern “C”

CMutual reference to C++ functions
Original address: http://blog.csdn.net/wfwd/archive/2006/05/30/763734.aspx
=========================================================================================
1.Introduction

  C++The original intention of the language is “a better C”, but this does not mean that C++ like global variables and functions in C language use the same compilation and connection method as C language. As a language compatible with C, C++ preserves some of the characteristics of procedural languages.People call it “incompletely object-oriented”, so it can define global variables and functions that do not belong to any class. However, C++ is an object-oriented programming language after all. In order to support the overloading of functions, the way C++ handles global functions is obviously different from C+.

2.Starting from the standard header file
A company has given the following interview question: Why do standard header files have the following structure?

  #ifndef __INCvxWorksh
  #define __INCvxWorksh 

  #ifdef __cplusplus
  extern “C” {
    #endif
    /*…*/
    #ifdef __cplusplus
  }
  #endif

  #endif /* __INCvxWorksh */

Obviously, the compiler macros’ ifndef INCvxWorksh, define INCvxWorksh, endif’in the header file prevent the header file from being referenced repeatedly. that

  #ifdef __cplusplus
  extern “C” {
    #endif
    #ifdef __cplusplus
  }
  #endif

  What is the role of it? We will come one after another.

3.Deep expose extern “C”

  extern “C” Double meanings can be obtained literally.

        First, the target it is decorated is “extern”.

        Secondly, the target it is decorated is “C”. Let us interpret these two meanings in detail.

  The function or variable defined by extern “C” is extern type.

  externC/C++ is a key word that indicates the scope (visibility) of functions and global variables, which tells the compiler that the declared functions and variables can be used in this module or other modules. Remember the following sentences:

    extern int a;

  A statement of variables is not a definition of variable a, but does not allocate memory space for a. The variable a can only be defined once as a global variable in all modules, otherwise a connection error will occur.

Typically, the functions and global variables that this module provides to other modules are declared with the keyword extern in the module header file.

For example, if module B wants to refer to the global variables and functions defined in module A, it only needs to include the header of module AThe piece can.

In this way, when module B calls a function in module A, module B does not find it at compile stage, but it does not report an error; it finds it in the connection stage from the object code compiled by module A.

The keyword corresponding to extern is static, which modifies global variables and functions that can only be used in this module. Therefore, a function or variable can only be used by this module, it can not be extern “C” decorated.

The variables and functions modified by extern “C” are compiled and connected in C language.

Compilation method without adding extern “C” Declaration

  First, let’s look at how a function similar to C is compiled in C++.

  As an object-oriented language, C++ supports function overloading while procedural language C does not support it. After the function is compiled by C++, the name in the symbol library is different from that in the C language. For example, suppose the prototype of a function is:

  void foo( int x, int y );

  The function is compiled by the C compiler with the name _foo in the symbol library, and the C++ compiler produces names like _foo_int_int (different compilers may generate different names, but all use the same mechanism.The new name is called “mangled name”.


  _foo_int_intSuch names contain function names, number of function parameters, and type information, and C++ relies on this mechanism to implement function overloading. For example, in C++, function void foo (int x, int y) and void foo (int x, int)T y) the symbols generated by compiling are different, and the latter is _foo_int_float.

  Similarly, variables in C++ not only support local variables, but also support class member variables and global variables. The class member variables that the user writes may have the same name as the global variables. We distinguish them by “.” In essence, compilers are similar to functions in compilation, and are variables in classes.Take a unique name, which is different from the global variable name of the same name in the user program.

Connection mode without extern “C” Declaration

Suppose that in C++, the header file of 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

  Referencing the function in module B:

// Module B to implement 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!

Compilation and connection after adding extern “C” Declaration

After adding the extern “C” statement, 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 invoked in the implementation file of module B, and the result is:

  (1)Module A compiles and generates the object code of foo without special treatment of its name, and adopts C language.

  (2)When the connector looks for a foo (2,3) call for the object code of module B, it looks for the unmodified symbol name _foo.

    If the function in module A declares that foo is of type extern “C” and module B contains extern int foo (int x, int y), module B cannot find the function in module A; vice versa.

  So, one sentence can be used to summarize the true purpose of the extern “C” statement (the birth of any grammatical feature in any language is not arbitrary, it is driven by real world needs. When we think about problems, we can not just stay in the language, but also ask it.Why do we do this and what motivations are, so that we can understand more deeply.
Realize the mixed programming of C++ and C and other languages.
  Understanding the motivation for setting up extern “C” in C++, let’s analyze the common use of extern “C” techniques.

4.extern “C”Idioms

  (1)Functions and variables in C++ are referenced, and when the C header file (assumed to be cExample. h) is included, the following processing is required:

    extern “C”
    {
      #include “cExample.h”
    }

  In the header file of C language, the external function can only be specified as an extern type. The extern “C” declaration is not supported in C language. Compiler syntax errors occur when extern “C” is included in the. C file.

  The C++ written by the author refers to the C function example. The source code of the three files contained in the project is as follows:

  /* cLanguage header file: cExample.h * /
  #ifndef C_EXAMPLE_H
  #define C_EXAMPLE_H
  extern int add(int x,int y);
  #endif


  /* cLanguage implementation file: cExample.c * /
  #include “cExample.h”
  int add( int x, int y )
  {
    return x + y;
  }
  // c++File implementation, calling add:cppFile.cpp
  extern “C”
  {
    #include “cExample.h”
  }
  int main(int argc, char* argv[])
  {
    add(2,3);
    return 0;
  }

  If C++ calls a. DLL written in C, you should extern “C” {} when header files containing. DLL or when declaring interface functions.

  (2)C++ header files need to add extern “C” when C++ functions and variables are referenced in C++, but this header file declaring extern “C” can not be directly referenced in C language. Only extern “C” functions defined in C++ should be used in C file.The declaration is extern type.
The C written by the author refers to the C++ function example. The source code of the three files contained in the project is as follows:

  //C++Header file cppExample.h
  #ifndef CPP_EXAMPLE_H
  #define CPP_EXAMPLE_H
  extern “C” int add( int x, int y );
  #endif


  //C++Implementation of file cppExample.cpp
  #include “cppExample.h”
  int add( int x, int y )
  {
    return x + y;
  }
  /* CImplementation of file cFile.c
  /* This will compile errors: #include “cExample.h” * /
  extern int add( int x, int y );
  int main( int argc, char* argv[] )
  {
    add( 2, 3 );
    return 0;
  }

Leave a Reply

Your email address will not be published. Required fields are marked *