|
|
HP C++ Programmer's Guide: HP 9000 Series Workstations and Servers > Chapter 5 Inter-Language CommunicationCalling HP C from HP C++ |
|
Since C++ is essentially a superset of C, calling between C and C++ is a normal operation. You should, however, be aware of the following:
The following sections discuss these issues. To handle overloaded function names the HP C++ compiler generates new, unique names for all functions declared in a C++ program. To do so, the compiler uses a function-name encoding scheme that is implementation dependent. A linkage directive tells the compiler to inhibit this default encoding of a function name for a particular function. If you want to call a C function from a C++ program, you must tell the compiler not to use its usual encoding scheme when you declare the C function. In other words, you must tell the compiler not to generate a new name for the function. If you don't turn off the usual encoding scheme, the function name declared in your C++ program won't match the function name in your C module defining the function. If the names don't match, the linker cannot resolve them. To avoid these linkage problems, use a linkage directive when you declare the C function in the C++ program. All HP C++ linkage directives must have either of the following formats:
For instance, the following declarations are equivalent:
and
You can also use a linkage directive with all the functions in a file, as shown in the following example. This is useful if you wish to use C library functions in a C++ program.
Although the string literal following the extern keyword in a linkage directive is implementation dependent, all implementations must support C and C++ string literals. Refer to "Linkage Specifications" in The C++ Programming Language, and to "Type-Safe Linkage for C++" in the C++ Language System Selected Readings for more details about linkage specifications. By default, the HP C++ compiler in translator mode does not generate function prototypes in the C code it creates. As a result HP C applies the argument widening rules of C without prototyping. This means that char and short types are promoted to int, and float is promoted to double. In programs written entirely in C++ this does not cause any problem, since the arguments are consistently handled within the program. However, if your C++ code calls functions written in C, you should make sure that the called C functions do not use function prototypes that suppress argument widening. If they do, your C++ code will be passing "wider" arguments than your C code is expecting. In translator mode you can use the +a1 option with CC to tell the translator to emit function prototypes in the C code it generates. When you use +a1, the linker links in the ANSI version of libC.a (or libC.sl), which is named libC.ansi.a (or libC.ansi.sl). Compiler mode is compatible with translator mode even though no C code is generated. In compiler mode, when you use +a0, the default, parameters of type float are promoted to type double. When you use +a1, float parameters are not promoted, but are passed as type float. When mixing C++ modules with C modules, the overall control of the program must be written in C++, with two exceptions. In other words, the main() function should appear in some C++ module, rather than in a C module. The exceptions are programs without any global class objects containing constructors or destructors and programs without static objects. Example 5-1 shows a C++ program, calling_c.C, that contains a main() function. In this example the C++ program calls a C function, get_name(). Example 5-2 shows the C function. Figure 5-1 Example 5-1. A C++ Program Calling a C Function
The following is example 5-2 showing the module get_name.c. This function is called by the C++ program in example 5-1. Figure 5-2 Example 5-2. A C Function Called by a C++ Program
Here's a sample run of the executable file that results when you link the object modules generated by compiling calling_c.C and get_name.c:
|
|