This code is often seen in the CPP code:
#ifdef __cplusplus
extern "C" {
#endif
//一段代码
#ifdef __cplusplus
}
#endif
What exactly does this code mean? First of all, __cplusplus is a custom macro in CPP, then the definition of the macro means that this is a CPP code, that is, the above code means: If this is a section of CPP code, then add extern "C" {and} to process the code.
To understand why extern "C" is used, you have to start with the overload handling of functions in CPP. In C + +, in order to support the overload mechanism, in compiling the generated assembler code, the to do some processing on the name of the function, such as the return type of the function, and so on. And in C, it's just a simple function name, and it doesn't add other information. That is, C + + and C have different processing of the function names produced.
For example, for the following simple function, let's look at the changes in the assembly code that is added and not added to extern "C":
int f(void)
{
return 1;
}
The assembly code generated when adding an extern "C" is:
.file "test.cxx"
.text
.align 2
.globl _f
.def _f; .scl 2; .type 32; .endef
_f:
pushl %ebp
movl %esp, %ebp
movl $1, %eax
popl %ebp
ret
But after the extern "C" is not added
.file "test.cxx"
.text
.align 2
.globl __Z1fv
.def __Z1fv; .scl 2; .type 32; .endef
__Z1fv:
pushl %ebp
movl %esp, %ebp
movl $1, %eax
popl %ebp
ret
The two pieces of assembly code are also produced using the Gcc-s command, all the places are the same, except the resulting function name, one is _f, one is __Z1FV.
Having understood the effect of adding and not joining extern "C" on the name of the function, we continue our discussion: Why do we need to use extern "C"? C + + Father in the design of C + +, considering that there is already a large number of C code, in order to support the original C code and has written C library, need to support C in C + +, and extern "C" is one of the strategies.
Imagine a situation where a library file is already written in C and works well, and we need to use this library file at this time, but we need to use C + + to write this new code. If this code uses C + + to link this C library file, then there will be a link error. Let's look at a piece of code: first, we use C to write a function, which is to say that the function was written in C:
//f1.c
extern "C"
{
void f1()
{
return;
}
}
The compile command is: gcc-c f1.c-o F1.O produces a library file called F1.O. Write another code to call this F1 function:
// test.cxx
//这个extern表示f1函数在别的地方定义,这样可以通过
//编译,但是链接的时候还是需要
//链接上原来的库文件.
extern void f1();
int main()
{
f1();
return 0;
}
by Gcc-c Test.cxx-o TEST.O produces a file called TEST.O. We then used gcc TEST.O f1.o to link two files, but there was an error, and the wrong hint was:
test.o(.text + 0x1f):test.cxx: undefine reference to 'f1()'
That is, when compiling Test.cxx compiler is to use C + + way to handle the F1 () function, but actually linked to the library file is in C way to deal with the function, so there will be a chain can not go to the error: because the linker cannot find the function.
Therefore, in order to call in C + + code in the library file written in, you need to use extern "C" to tell the compiler: This is a C-written library files, please use the C way to link them.
For example, now we have a C library file, its header file is f.h, the resulting lib file is f.lib, then if we want to use this library file in C + +, we need to write this:
extern "C"
{
#include "f.h"
}
To get back to the problem above, if you want to correct the link error, we need to rewrite test.cxx:
extern "C"
{
extern void f1();
}
int main()
{
f1();
return 0;
}
Recompile and the link will pass.
Summarize
C and C + + are different ways of handling functions. extern "C" is a means to enable C + + to invoke C writing library files, if you want to prompt the compiler to use C to handle functions, then use extern "C" to explain.