Odnośniki


[ Pobierz całość w formacie PDF ]

void func(int);, a given compiler can generate the corresponding
mangled name __x_func@i@, where the affix x indicates a function, func
is the function's user-given name, @ indicates the beginning of the
parameter list, i indicates the type of the parameter, and the closing @ sign
signals the end of the parameter list. An overloaded version of f() has a
different mangled name because it has a different parameter list. The
original user-given name can be reproduced from the mangled name, so
linkers in general can issue error messages in a human-readable format.
As was previously stated, the name mangling scheme of a given compiler
can change from one version to another (for example, if the new version
supports namespaces, whereas the previous one did not). This is one of the
reasons you often have to recompile your code with every compiler
upgrade. Another important implication is that, usually, the linker and the
compiler need to come from the same vendor and have compatible
versions. This ensures that they share the same naming conventions and
that they produce compatible binary code.
Calling C++ Code from C Code
Up until now, you have observed the C++ side of the story. A C program cannot
#include the header file decl.hpp because the extern "C" specifier is not recognized
by a C compiler. To ensure that the declaration can be parsed by a C compiler, extern
"C" needs to be visible to a C++ compiler -- but not to a C compiler. A C++ function
with C linkage has to be declared in two distinct forms, one for C++ and another for C.
This can be achieved by using separate C and C++ header files. The C header file looks
similar to the following:
/*** filename decl.h ***/
void f(int n); /* identical to the C++ header but no extern "C" here
*/
/*** decl.h ***/
The header file can be #included in the C source file that calls the function f(). For
example
/*** filename do_something.c ***/
#include "decl.h"
void do_something()
{
f(5);
}
/*** do_something.c ***/
Keeping separate header files for C and C++ is not an elegant solution, however. The
header files have to remain in sync all the time, and when many header files are used, this
can turn into a serious maintenance problem. A better alternative is to use one or more C
header files for the declarations. For example
/*** filename f.h ***/
void f(int n); /* identical to the C++ header but no extern "C" here
*/
/*** f.h ***/
/*** filename g.h ***/
void g(const char * pc, int n);
/*** g.h ***/
Next, the C header files are #included in a C++ header file that contains an extern "C"
block:
// filename decl.hpp
extern "C"
{
#include "f.h"
#include "g.h"
}
// filename decl.hpp
The effect of an extern "C" block is as if every declaration in the #included header
files had a preceding extern "C" specifier. Another alternative is to modify the C header
file directly by adding an #ifdef directive to make the extern "C" declaration visible
only to a C++ compiler. For example
/*** filename decl.h ***/
#ifdef __cplusplus
extern "C" { //visible only to a C++ compiler
#endif
void g(const char * pc, int n);
void f(int n);
#ifdef __cplusplus
} //visible only to a C++ compiler
#endif
/*** g.h ***/
This way, only one header file is needed. However, it is not always possible to modify
the C header files directly. In such cases, the preceding technique needs to be used.
Please note that a C++ function called from C code is an ordinary C++ function. It can
instantiate objects, invoke their member functions, or use any other C++ feature.
However, some implementations might require special configuration settings to ensure
that the linker has access to the C++ libraries and template codes.
Compiling main()
Functions can be compiled by either a C compiler or a C++ compiler. However, a C++
compiler should compile main(). This enables a C++ compiler to take care of templates,
static initialization, and additional implementation-dependent operations for which
main() is responsible. Compiling main() under a C compiler will most likely result in
link-time errors due to the different semantics of main() in C and C++.
Minimize the Interface Between C and C++ Code
In general, you can call a C function from C++ code without special adjustments. The
opposite, as you have seen, is also possible -- but it requires additional adjustments. It is
therefore recommended that you keep the interface between the two languages at a
minimum. Declaring every C++ function as extern "C", for example, is not
recommended. Not only does this convention imply additional modifications to the
header files, it also disables overloading. Remember also that you cannot declare a
member function extern "C". For C++ functions that have to be called from C code, it
might be advantageous to use a function wrapper that has an extern "C" specifier. In
this case, the wrapped C++ functions can have the C++ linkage. For example
void g(const char * pc, int n); //extern "C" is unnecessary
void f(int n);
extern "C" void f_Wrapper(int n) //only the wrapper function is called
from C
{
f(n);
}
extern "C" void g_Wrapper(const char *pc, int n)
{
g(pc, n);
}
Mixing Classes with Functions
It is possible to use both classes and library functions in the [ Pobierz całość w formacie PDF ]
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • brzydula.pev.pl

  • Sitedesign by AltusUmbrae.