C And C

 < Day Day Up > 



C++ And C

As a C++ programmer you will encounter many situations requiring you to incorporate legacy C code into your programs. A good example of this is when you find a good C standard library function that does exactly what you need. Often, however, C++ programmers find themselves converting a legacy C application to C++. In either case, this section will explain how to use separately compiled C libraries in your programs by using the extern keyword, and, more importantly, why you need to use the extern keyword.

How C++ Allows Overloaded Functions: Name Mangling

C++ and C are different in many ways. One important difference between the two languages is that C++ allows function overloading while C does not. A C++ compiler employs a function name transformation process known as name mangling that converts function names (and other object names within a C++ program) into a form that ensures uniqueness. The C language does not support function overloading and therefore does not need to mangle names.

What does this mean to you the C++ programmer? It means that library code written in C can be used in a C++ program but you have to inform the C++ compiler that the function names of the functions contained in the C library are not mangled, or else the names of the functions appearing in the library code cannot be resolved by the linker to where they appear in the C++ source code. To help in this matter you need to use the extern linkage specifier.

extern Keyword

To prevent the C++ compiler from name mangling a C function declaration use the extern keyword to specify the type of language linkage to perform. To illustrate how this is done I will walk you through a complete example that creates a C static library with one function named square(). This library will then be used in a C++ program to illustrate what happens when you try to link to the library without using extern and how extern is applied to resolve the situation.

Building a C Library: The square() Function

The C code library containing the square() function will be created using the steps shown in chapter 9 in the section Steps To Creating a Library. They are repeated here for your convenience but I must stress that the exact steps employed to create your code libraries will depend on your development environment.

  • Step 1 - Put the function declarations for any functions you want in the library in a header file. (.h file)

  • Step 2 - Put the definitions for the library functions in a separate implementation file. (.c file)

  • Step 3 - Create an empty project in an integrated development environment and add the implementation file to it.

  • Step 4 - Add any library files to the project required to support the implementation file.

  • Step 5 - Set the required target settings for the project.

  • Step 6 - Name the library output file and set project type.

  • Step 7 - Compile the project.

  • Step 8 - Use the library!

Step 1: Create square.h Header File

The code for square.h is shown in example 18.1.

Listing 18.1: square.h

start example
 1  #ifndef SQUARE_H 2  #define SQUARE_H 3 4  double square(double d); 5 6  #endif
end example

Step 2: Create square.c Implementation File

The code for square.c is shown in example 18.2

Listing 18.2: square.c

start example
 1  #include "square.h" 2 3  double square(double d){ 4      return d*d; 5  }
end example

Step 3: Create Empty Project with IDE and Add Implementation File

Metrowerks CodeWarrior will be used to create the empty project named Square_Lib. Figure 18-1 shows the New Project window.

click to expand
Figure 18-1: Creating a New Empty Project Named Square_Lib in CodeWarrior

This results in an empty project window as shown in figure 18-2:

click to expand
Figure 18-2: Empty Project Window

Select Add Files... from the Project menu to add the square.c file to the Square_Lib project as shown in figures 18-3 and 18-4.

click to expand
Figure 18-3: Select Add Files... from the Project Menu


Figure 18-4: Select square.c to Add it to the Project

Figure 18-5 shows the project window after adding the square.c file.

click to expand
Figure 18-5: Project Window After Adding square.c

Step 4: Add Necessary Supporting Library Files To Project

No supporting library files are required for the square() function.

Step 5: Set Required Target Settings

Because an empty project was created you must make several project settings before the square.c file can be compiled. Select Square_Lib Settings...from the Edit menu as shown in figure 18-6. This will bring up the Settings window as shown in figure 18-7.

click to expand
Figure 18-6: Select Square_Lib Settings...from the Edit Menu

click to expand
Figure 18-7: Settings Window with Target Settings Selected

The Target Settings are set as indicated in figure 18-7. The Target Name is set to Square_Lib and the Linker selected is MacOS PPC Linker.

Step 6: Name the Library File and Set Project Type

After making the target settings select PPC Target and set the Project selection to Library and name the library file name to square.lib as shown in figure 18-8. When finished making the necessary target settings click the Save button.

click to expand
Figure 18-8: Setting Project Type and Library File Name

Step 7: Compile the Project

Before closing the settings window and compiling the library select the C/C++ Language settings to ensure you are creating a C library function and not a C++ library function. This is done in CodeWarrior by ensuring the Activate C++ Compiler check box is not checked as shown in figure 18-9.

click to expand
Figure 18-9: Ensure the Activate C++ Compiler Check Box is Not Checked

After checking the language settings the square.lib file can be created by making the project. Do this by selecting Make from the Project menu as shown in figure 18-10.

click to expand
Figure 18-10: Select Make from the Project Menu to Create the square.lib File

Once the square.lib library file is created it can be used in another project. This is illustrated in step 8 below.

Step 8: Use the Library

OK, in steps 1 through 7 above a C library function named square() was created and placed in a static library file named square.lib. In this step the square() function will be used in a C++ program. The C++ program in this example is simply a main() function that calls the square() function which was written in C. The code for the main.cpp file is given in example 18.3. Notice on line 2 of example 18.3 that the square.h header file given in example 18.1 is included. The C++ project window with the square.lib library file added is shown in figure 18-11.

Listing 18.3: main.cpp

start example
 1   #include <iostream> 2   #include "square.h" 3   using namespace std; 4 5   int main(){ 6       cout<<square(5)<<endl; 7       return 0; 8   }
end example

click to expand
Figure 18-11: C++ Project Window with square.lib Library File Added.

OK, drum roll. An attempt to build the project as-is results in the link error shown in figure 18-12.

click to expand
Figure 18-12: Link Error Resulting from First Attempt to Build the C++ Project that Uses a C Function

The link error was produced because the square() function library was created in the C programming language. The C++ compiler is mangling the name of the square() function and because the square() function's name is not mangled in the C library the C++ linker cannot resolve the mangled function name with the non-mangled function name. What you must do to get the C++ project to work is modify the square.h header file in a way that tells the C++ compiler not to mangle the square() function name. You do this with the extern keyword as shown in example 18.4.

Listing 18.4: modified square.h

start example
 1   #ifndef SQUARE_H 2   #define SQUARE_H 3 4   extern "C"{ 5   double square(double d); 6   } 7 8   #endif
end example

Referring to example 18.4, the square() function is declared to be of type C language linkage by wrapping it inside of an extern 'C'{ } declaration. This will indicate to the C++ compiler that this function was written in C vice C++. After this modification is made to the square.h header file the project can now be built with no link errors. The results of running the C++ project are shown in figure 18.13.

click to expand
Figure 18-13: Results of Running the C++ Project Using the C square() Function

It should be noted now that the exact usage of the extern language linkage declaration is implementation dependent. Some compilers require an uppercase C while others will accept either an upper case C or a lower case c.

Deciphering C Standard Library Files

Now that you understand how to incorporate C library functions into your C++ programs using the extern keyword you can unlock the mysteries of the C Standard Libraries. Up to this point you may have used functions from the C standard libraries in your C++ programs without a second thought. However, if you examine the C library files you will discover the C function declarations are wrapped in extern declarations. Now you know why.

Quick Review

The extern 'C' language linkage specification is used to link C language routines with C++ programs. The distinction between C and C++ function names is necessary due to C++ name mangling. If a C function declaration omits the extern 'C' linkage specification then the C++ compiler will not be able to resolve the mangled function name with the non-mangled name found in the C library file.

Other high-level programming languages can be used with C++ in similar fashion. The extern keyword can be used to specify not only 'C' linkage but also 'FORTRAN' and 'PASCAL'. Other linkage specifications may also be supported by different compiler manufacturers.



 < Day Day Up > 



C++ for Artists. The Art, Philosophy, and Science of Object-Oriented Programming
C++ For Artists: The Art, Philosophy, And Science Of Object-Oriented Programming
ISBN: 1932504028
EAN: 2147483647
Year: 2003
Pages: 340
Authors: Rick Miller

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net