When C calls the library function of C, if the header file is incorrectly defined, a function may exist in the obj file but the link fails. the following error occurs:
Undefined reference to xxx
The cause of the problem is that the function symbols in the c library are different from those in the C library when the function is compiled into the obj file. Because C Functions Support overloading, the processing of function symbols is more complex, and c is often not modified.
For example, there are functions:
/* Dofunc. c */
# Include <stdio. h>
Int dofunc ()
{
Printf ("dofunc ");
}
After compiling with gcc into obj
Gcc-c dofunc. c
# Generate dofunc. o
Objdump-x dofunc. o
[0] (sec-2) (fl 0x00) (ty 0) (scl 103) (nx 1) 0x00000000 dofunc. c
File
[2] (sec 1) (fl 0x00) (ty 20) (scl 2) (nx 1) 0x00000000 _ dofunc
AUX tagndx 0 ttlsiz 0x0 lnnos 0 next 0
[4] (sec 1) (fl 0x00) (ty 0) (scl 3) (nx 1) 0x00000000. text
AUX scnlen 0x14 nreloc 2 nlnno 0
[6] (sec 2) (fl 0x00) (ty 0) (scl 3) (nx 1) 0x00000000. data
AUX scnlen 0x0 nreloc 0 nlnno 0
[8] (sec 3) (fl 0x00) (ty 0) (scl 3) (nx 1) 0x00000000. bss
AUX scnlen 0x0 nreloc 0 nlnno 0
[10] (sec 4) (fl 0x00) (ty 0) (scl 3) (nx 1) 0x00000000. rdata
AUX scnlen 0x8 nreloc 0 nlnno 0
[12] (sec 0) (fl 0x00) (ty 20) (scl 2) (nx 0) 0x00000000 _ printf
The dofunc function of c is signed as _ dofunc In the obj file.
Let's look at the compiled code using g:
G-c dofunc. c
Objdump-x dofunc. o
Symbol table:
[0] (sec-2) (fl 0x00) (ty 0) (scl 103) (nx 1) 0x00000000 dofunc. c
File
[2] (sec 1) (fl 0x00) (ty 20) (scl 2) (nx 1) 0x00000000 _ Z6dofuncv
AUX tagndx 0 ttlsiz 0x0 lnnos 0 next 0
[4] (sec 1) (fl 0x00) (ty 0) (scl 3) (nx 1) 0x00000000. text
AUX scnlen 0x14 nreloc 2 nlnno 0
[6] (sec 2) (fl 0x00) (ty 0) (scl 3) (nx 1) 0x00000000. data
AUX scnlen 0x0 nreloc 0 nlnno 0
[8] (sec 3) (fl 0x00) (ty 0) (scl 3) (nx 1) 0x00000000. bss
AUX scnlen 0x0 nreloc 0 nlnno 0
[10] (sec 4) (fl 0x00) (ty 0) (scl 3) (nx 1) 0x00000000. rdata
AUX scnlen 0x8 nreloc 0 nlnno 0
[12] (sec 0) (fl 0x00) (ty 20) (scl 2) (nx 0) 0x00000000 _ printf
G compiled function Symbol names are odd: __z6dofuncv
It can be seen that C and C are very different in processing function names.
If a C program uses dofunc. o, the function declaration of the following program is incorrect.
// Main_dev.cpp
Int dofunc ();
Int main (int argc, char * args [])
{
Dofunc ();
System ("pause ");
}
G-o main_dev main_dev.cpp dofunc. o
Main_dev.cpp: undefined reference to 'dofunc ()
Collect2: ld returned 1 exit status
The reason is that the dofunc function name should be _ Z6dofuncv after processing, and the dofunc. o file contains _ dofunc, so it cannot be found.
If the source code of dofunc is available, the solution is simple. Compile dofunc. c with c.
If the dofunc function is unfortunately stored in another library, which is compiled in c and gcc, and the source code is invisible, what should we do?
Fortunately, the designers of C and compiler have long expected this problem and provided a general solution: Use extern "C" to modify the external function declaration of the old C library.
Extern "C "{
Int dofunc ();
}
Int main (int argc, char * args [])
{
Dofunc ();
System ("pause ");
}
G-o main_dev main_dev.cpp dofunc. o
Successful
All the functions modified by extern "C" are compiled according to the c style, so that they can be linked to the obj library compiled by c.
Common tangible objects include:
_ Cplusplus is defined by the c compiler, which ensures that extern "C" takes effect during C compilation; when compiling with c, it will not cause errors because it will not process extern "C.
What if c needs to call the C-compiled library? I believe that there will not be such a strange requirement in general, but it is not enough to compile it directly with C?
Rename main_dev.cpp to main. c, and then
Gcc-o main_dev main_dev.c dofunc. o
Of course: undefined reference to 'dofunc
Because the symbol in fofunc. o is _ Z6dofuncv, the link will fail. There is only one disgusting way to link to that function:
// Main_dev.c
Int (* dofunc) ();/* declare function pointer */
Int _ Z6dofuncv ();/* is linked to _ Z6dofuncv */
Int main (int argc, char * args [])
{
Dofunc = _ Z6dofuncv;/* function pointer assignment */
Dofunc ();
System ("pause ");
}
Gcc-o main_dev main_dev.c dofunc. o
Successful
As mentioned above, the central meaning is the details of function name processing during c and c compilation and linking. After understanding these details, how to use them will be completely focused.
# Ifdef _ cplusplus
Extern "C "{
# Endif
Int dofunc ();
# Ifdef _ cplusplus
}
# Endif header file declaration.
This header file is generally provided by the Library developer and can be used by both the c and c modules.