Call C's library function in C + + (reprint)

Source: Internet
Author: User

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)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.