Advanced C++ - Part IIIa (Creating Libraries)


Creating Libraries

We still haven’t achieved implementation hiding in the real sense. Any user of your class can open the *.cpp files and modify your function definitions. Generally, the creator of a class wouldn’t want to let a user do this. Also, the user will now have to copy the car.cpp file into his project directory and compile it before he can run his program. Wouldn’t it be simpler if the user could just put a #include statement in his project without having to bother about someone else’s *.cpp files?

This is where a library comes into the picture. The class creator can create a library file as well. When others want to use his class, they have to just include his header file and also ask the linker to search for the class implementation in the new library. A library is a collection of object files (i.e. the output of the compiler stage). Let’s create a library to make the concept clear. (We’ll look at the process to be followed in VC++. The appendix section will deal with C++ on Unix/Linux).

First we’ll need to create a library. Go to File and choose New. In the options tab choose Projects.

Name the project as carlib and click the OK button. The next dialog box will ask if you want to include MFCs or other files. Don’t choose any of these (for this library we don’t require anything extra).

Add a new header file (carlib.h) to this project. Include the following code:

//carlib.h
#include <iostream>
using namespace std;

class car
{
private:
    char color[20];
    int speed;

public:
car( );
void input( );
void display( );
~car( );
};

Include a source file (named car.cpp) in this project. The code for this will contain the implementation details of the class ‘car’.

#include "carlib.h"

car::car( )
{
cout<<endl<<"New car created.";
}

void car::input( )
{
cout<<endl<<"Enter the color : ";
cin>>color;
cout<<endl<<"Enter the top speed : ";
cin>>speed;
}

void car::display( )
{
cout<<endl<<"The color is : "<<color;
cout<<endl<<"The top speed is : "<<speed;
}

car::~car( )
{
cout<<endl<<"Your car is destroyed.";
}

Now compile car.cpp. If you have no errors then go to ‘Build’, and choose the option "build carlib.lib". If there are no errors then you are successful in creating your library. How does one use this?

If someone wants to use your library then all you need to do is supply them with the carlib.lib file and carlib.h header file. The *.lib file contains the object code while the carlib.h file just contains the interface to your class. Anyone who uses your class can take a look at the *.h file to know what functions are available for them to use (of course for a more complex class you would have to provide some documentation in the header file).

Let’s use this library in a program to check if it works. Create a new application project and include a C++ source file into the project. Name it as mycar.cpp and type the following code:

//mycar.cpp
#include "carlib.h"
int main( )
{
car mine;
mine.input( );
mine.display( );
return 0;
}

Now compile mycar.cpp and voila! You should have an error saying:

c:\tutorial\mycar\mycar.cpp(2) : fatal error C1083: Cannot open include file: 'carlib.h': No such file or directory

The error message is self-explanatory. We haven’t told the compiler as to where the file carlib.h is present. You have 2 options at this point:

  1. Copy that file into your current project directory and include it in this project.
  2. Your compiler will search for include files in particular directories. You can add the name of the directory where your *.h file is present to this list (this is usually present in the Project Settings option).

Since we are planning to distribute our library to a 3rd person, we’ll take the first route. Copy the file carlib.h into your current project directory. Then go to VC++ and make sure that you include this file into your current project (otherwise VC++ will not consider this file as part of the project even though it is physically present in the same directory).

For doing this go to PROJECT -> Add to Project -> Files and choose the header file.

Now compile mycar.cpp. You shouldn’t have any errors this time. The next step is to build the exe file mycar.exe. Go to ‘BUILD -> Build mycar.exe’ option.

Well, you should be getting a bunch of errors this time (which might appear weird). The following messages appeared in my computer:

Linking...

mycar.obj : error LNK2001: unresolved external symbol "public: __thiscall car::~car(void)" (??1car@@QAE@XZ)

mycar.obj : error LNK2001: unresolved external symbol "public: void __thiscall car::display(void)" (?display@car@@QAEXXZ)

mycar.obj : error LNK2001: unresolved external symbol "public: void __thiscall car::input(void)" (?input@car@@QAEXXZ)

mycar.obj : error LNK2001: unresolved external symbol "public: __thiscall car::car(void)" (??0car@@QAE@XZ)

Debug/mycar.exe : fatal error LNK1120: 4 unresolved externals

Error executing link.exe.

Don’t panic on seeing the strange symbols. From the error messages we can deduce that this is a linker error (compiling went fine but linking failed). Why? If you look at the individual messages you’ll realize the problem. The linker hasn’t been able to resolve references to certain function definitions (car::~car( ), car::display( ) etc.). They are not present in carlib.h, not in mycar.cpp and certainly not in #include<iostream>.

So, should we add car.cpp to this file (but then we are not using the power of libraries). Car.cpp contains the definitions of these functions but carlib.lib contains the object code for all these functions. The linker only requires the object code for the functions and hence we should include the library carlib.lib in our current project. Then the linker will search carlib.lib and find the required object code for all the definitions. To do this, there are 2 settings you have to change in your project:

  1. Tell VC++ the path where to search for the libraries.
  2. Tell VC++ the name of the library.

The rest of this section is added in the next page (since putting too many pics on one page will take lots of time to download).


Copyright © 2004 Sethu Subramanian All rights reserved.