C ++ calls C library functions

Source: Internet
Author: User

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.

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.