Transferred from: http://linhs.blog.51cto.com/370259/140927
When C + + calls the library function of C, if the header file is not properly defined, there may be a situation where a function is present in the obj file but the link fails, and the following error occurs:
Undefined reference to ' xxx '
The problem occurs because the C library functions are compiled into an obj file, and the function symbols are treated differently from C + +. Because C + + functions support overloading, the processing of function symbols is more complicated and c is often not decorated.
For example, there are functions:
/**/<stdio.h>int dofunc () { printf (" dofunc\n");}
After using GCC to compile into obj
GCC-c dofunc.c# Generate Dofunc.oobjdump-x dofunc.o[0] (Sec-2) (fl0x00) (Ty0) (SCL103) (NX1)0x00000000dofunc.cfile[2] (sec1) (fl0x00) (Ty -) (SCL2) (NX1)0x00000000_dofuncaux tagndx0Ttlsiz0x0Lnnos0Next0[ 4] (sec1) (fl0x00) (Ty0) (SCL3) (NX1)0x00000000. Textaux Scnlen0x14Nreloc2Nlnno0[ 6] (sec2) (fl0x00) (Ty0) (SCL3) (NX1)0x00000000. Dataaux Scnlen0x0Nreloc0Nlnno0[ 8] (sec3) (fl0x00) (Ty0) (SCL3) (NX1)0x00000000. Bssaux Scnlen0x0Nreloc0Nlnno0[ Ten] (sec4) (fl0x00) (Ty0) (SCL3) (NX1)0x00000000. Rdataaux Scnlen0x8Nreloc0Nlnno0[ A] (sec0) (fl0x00) (Ty -) (SCL2) (NX0)0x00000000_printf
The Dofunc function of C in the obj file is signed as _dofunc
Then look at the compiled code using g++:
g++-C Dofunc.cobjdump-x dofunc.osymbol table:[0] (Sec-2) (fl0x00) (Ty0) (SCL103) (NX1)0x00000000dofunc.cfile[2] (sec1) (fl0x00) (Ty -) (SCL2) (NX1)0x00000000__z6dofuncvaux tagndx0Ttlsiz0x0Lnnos0Next0[ 4] (sec1) (fl0x00) (Ty0) (SCL3) (NX1)0x00000000. Textaux Scnlen0x14Nreloc2Nlnno0[ 6] (sec2) (fl0x00) (Ty0) (SCL3) (NX1)0x00000000. Dataaux Scnlen0x0Nreloc0Nlnno0[ 8] (sec3) (fl0x00) (Ty0) (SCL3) (NX1)0x00000000. Bssaux Scnlen0x0Nreloc0Nlnno0[ Ten] (sec4) (fl0x00) (Ty0) (SCL3) (NX1)0x00000000. Rdataaux Scnlen0x8Nreloc0Nlnno0[ A] (sec0) (fl0x00) (Ty -) (SCL2) (NX0)0x00000000_printf
g++ compiled function symbol name is more eccentric:__Z6DOFUNCV
It can be seen that C and C + + are very different in terms of processing function names.
If you have a C + + program to use DOFUNC.O, the following program's function declaration is wrong
// Main_dev.cpp int Dofunc (); int Main (intChar* args[]) { dofunc (); System ("pause");} G+ + -o main_dev main_dev.cpp dofunc.omain_dev.cpp:undefined reference to ' Dofunc ()' 1 exit status
The reason is that the Dofunc function after the processing function name should be __Z6DOFUNCV , DOFUNC.O file inside is _dofunc, so can not find.
If there is Dofunc source code, the solution is very simple, will dofunc.c use C + + to compile.
If unfortunately the Dofunc function in someone else's library, and this library is written in C and GCC compiled, the source code is not visible, how to do?
Fortunately, the designers of C + + and compilers have long anticipated this problem and provided a common workaround: use extern "C" to modify the external function declaration of the old C library.
extern " C " {int dofunc ();} int Main (intChar* args[]) { dofunc (); System ("pause");} G+ + -o main_dev main_dev.cpp dofunc.o Success
The functions in the extern "C" modifier are compiled according to the C style, so that they can be linked to the obj library compiled with C.
Common tangible such as:
#ifdef __cplusplus extern " C " {#endifint dofunc (); #ifdef __cplusplus} #endif
The header file declaration.
This header file is typically provided by the library developer and can be used by both C and C + + modules. Macro __cplusplus is defined by the C + + compiler, which ensures that extern "C" is compiled with C + +, and that C compiles without errors because it does not handle extern "C".
Conversely, what if C needs to call a C + + compiled library? Believe that the general situation will not have such a peculiar requirement, the direct use of C + + compilation is not finished?
Rename the main_dev.cpp to Main.c, and then
Gcc-o Main_dev main_dev.c DOFUNC.O
Of course it will appear: undefined reference to ' Dofunc '
Because the symbol inside the FOFUNC.O is __z6dofuncv , the link fails and there is only one very disgusting way to link to that function:
//main_dev.cint(*dofunc) ();/*declaring function Pointers*/int_Z6DOFUNCV ();/*will be linked to __Z6DOFUNCV*/intMainintARGC,Char*args[]) {Dofunc=_Z6DOFUNCV;/*function pointer Assignment value*/Dofunc (); System ("Pause");} GCC-o main_dev main_dev.c dofunc.o Success
It says so much, the central meaning is the C and C + + compile and link to the function of the name processing details, after understanding these details, how to use completely in the heart.
above humble opinion, welcome correction .
This article is from the Software Craftsman notes blog, so be sure to keep this source http://linhs.blog.51cto.com/370259/140927
Call C's library function in C + + (reprint)