(Not my original, this note, with the table of the original author of the admiration of http://blog.163.com/sean_1010/blog/static/11080322200952633111975)
Assume that the old cProgramLibrary
C header file
/* ----------- C. H --------------*/
# Ifndef _ C_H _
# DEFINE _ C_H _
Extern int add (int x, int y );
# Endif
C source file
/* ----------- C. c --------------*/
Int add (int x, int y ){
Return X + Y;
}
C ++ calls
/* ----------- CPP. cpp --------------*/
# Include "C. H"
Void main ()
{
Add (1, 0 );
}
In this case, an error CPP. OBJ: Error lnk2001: unresolved external symbol "int _ cdecl add (INT, INT)" ([email =? Add @ yahhh @ Z]? Add @ yahhh @ Z [/Email]) because the target module of add cannot be found.
This reminds me of the C ++ overload function naming method and the C function naming method. Let's review: after the function is compiled in C, it is named "_" before the function name. For example, when the Add function is compiled into an OBJ file, it is actually named _ add, while C ++ is named differently, in order to implement function overloading, the same function name Add will be compiled into different names due to different parameters.
For example
Int add (INT, INT) ==> add @ yahhh @ Z,
Float add (float, float) ==> add @ yammm @ Z,
The above is the naming method of vc6. Different compilers may be different. In short, the same function name with different parameters will be compiled into different target names, so that function overloading can call specific functions.
Compile CPP. in CPP, the compiler finds the call to add (1, 0); in the CPP file, and the function declaration is extern int add (int x, int y ); the compiler decides to go to [email = add @ yahhh @ Z] add @ yahhh @ Z [/Email]. Unfortunately, he cannot find it, because the source file of C has compiled extern int add (int x, int y) into _ add;
To solve this problem, C ++ adopts extern "C", which is our topic. To use the previous C library, you must learn it, you can see the following standard header files. You will find that many header files have the following structure:
# Ifndef _ H
# DEFINE _ H
# Ifdef _ cplusplus
Extern "C "{
# Endif
Extern int F1 (INT, INT );
Extern int F2 (INT, INT );
Extern int F3 (INT, INT );
# Ifdef _ cplusplus
}
# Endif
# Endif/* _ H */
If we copy this header file, we can get
# Ifndef _ C_H _
# DEFINE _ C_H _
# Ifdef _ cplusplus
Extern "C "{
# Endif
Extern int add (INT, INT );
# Ifdef _ cplusplus
}
# Endif
# Endif/* _ C_H _*/
Compile in this way
/* ----------- C. c --------------*/
Int add (int x, int y ){
Return X + Y;
}
In this case, the source file *. c ,__ cplusplus is not defined, and extern "C" {} does not take effect. For C, only extern int add (INT, INT) is seen );
Compile the Add function into _ add (INT, INT );
Compile the C ++ source file
/* ----------- CPP. cpp --------------*/
# Include "C. H"
Void main ()
{
Add (1, 0 );
}
The source file is *. CPP ,__ cplusplus is defined. For C ++, what he sees is extern "C" {extern int add (INT, INT);} the compiler will know add (1, 0); The called C-style function will know to go to C. find _ add (INT, INT) in OBJ instead of [email = add @ yahhh @ Z] add @ yahhh @ Z [/Email];
This is why extern "C" {} is often seen in the DLL. In Windows, the C language is used for compiling. First, consider that C can call these DLL correctly, the user may use C ++ and extern "C" {} will function.
When the header file written in the original C language does not consider this issue, you can write it as follows:
# Include <XXXXX. h>
# Include <yyyyy. h>
Extern "C "{
# Include "sift. H"
# Include "imgfeatures. H"
# Include "kdtree. H"
# Include "utils. H"
# Include "XForm. H"
}
In this way, you can use the C language written by others in C ++.