Saturday, 30 June 2007

Library - Reusable binary component

In our daily development activities, we will come across various types of libraries. Like Static Library, Dynamic Linked Library, Plugins etc,


In this article, I have tried to explain each of these.


You consider any type of library, final objective will remain the same - Binary Reusability.


Developer should identify a set of re-usable components or routines in his module and create a library. So that, this can be distributed and used by anyone instead of rewriting the components again.


Lets start from Static Library(.lib) (called as Archive in unix world). Usually libraries will be create with .lib extension (.a in unix). The idea behind static library is to create a reusable binary module that can be linked with any executable or another dynamic library, so that it can reuse the static library components. Linking/Binding module will have the responsibility of linking your executable with the static library. Hence the final size of the executable will be original executable code size + the static library code size. The executable will embed the static library within.




All the routines and components which were present in the static library can be directly used as if they were implemented in the same module.


After compilation, at link time the linker module will look for all the symbols which were referenced in the executable and tries to link the static library. The developer has to specify the static library so that the linker can link it with the executable.



Dynamically Linked Library (DLL): Generally we export functions or routines from DLLs. When we say export that means those are all the entry points for the executables that are linked with it. Only the exported functions can be accessed by the executables.


We can use the DLLs in two ways. One way is to link the static interface of a DLL with an executable and another is to load the DLL at run-time. Both have its own advantages.


Statically linking the DLL interface : For any DLL, there will always be a static library(.lib) generated. This static library is just an interface to the DLLs exported functions, they wont have any definitions for the exported functions. They are just like routers to the actual definition which is present in the DLL.


Executables can link to this static library and use the exported functions in the DLL. The executable will just have DLLs interface embedded in it. DLL will be a separate module which will be loaded by the loader when we start the executable.






In this method, the DLL will be loaded when we start the executable. The life span of the exe along with the DLL can be depicted as below,



Loading a DLL at Run-time : This is the second way of using a DLL. Where we can use certain System API's to load the DLL at run-time. The static interface for the DLL is not used in this case. A typical example is shown below.



// Load the library
MyDll = LoadLibrary("C:\\MyWork\\aDll.dll");

// Get address of exported function
FuncPointer = GetProcAddress(MyDll, "SomeExportedFunc");

// Make call
FuncPointer();

// Release the library
FreeLibrary(MyDll)


Note here that, the DLL can be loaded and released at any point of time with in the life span of the exe. Which is different from the previous method where it would load it at the start of the execution itself.


A Plugin is an extension to this method. Lets talk about this in further articles.

Cheers!

Friday, 29 June 2007

Can access a private function?

Today, at lunch time, Anand had a slip in his hand with C++ code written on it. He was smiling showing that to me and asking to tell how the code behaves.

As usual he had a great feeling of discovering some new thing ;)

I had to watch the code, it goes like below

Class CBase
{
    public:
        virtual void vfunc()
        {
            // Some definition
        }
};

 

Class CDerived : public CBase
{
    private:
        void vfunc()
        {
            // Some definition
        }
};

 

int main()
{
    CBase *pBase = new CDerived();
    pBase->vfunc();
}

CBase has a virtual function vfunc which is overridden in CDerived. In the main routine we are making a base pointer to point to the derived class instance. Then we are calling the vfunc.

The main point to note here is - CDerived::vfunc() is private.

Even the function is declared as private its accessible! when we do

pBase->vfunc();

Strange!

This is because the real call to the function is made thru virtual pointer.

We wouldn't be able to access the same function via an instance of CDerived. Isn't it?

What to say about this? Is this a design flaw? A loop hole? or just say "This is what C++ is"!

Sunday, 24 June 2007

dynamic_cast

Lets talk about Dynamic Casting today!

dynamic_cast is one of the four C++ casting operators (static_cast, dynamic_cast, reinterpret_cast and const_cast), extensively used in case of polymorphic types.

Unlike C type casting which does a static type check, this will do a type check at run time. If the casting is invalid, it either throws bad_cast exception or returns a NULL pointer.

This has to be used for safe run-time down casting.

What is Down casting?

Casting a superclass pointer (or reference) into a pointer (or reference) to a subclass in a class hierarchy is said to be down casting.

Typical example looks like this,


CDerived *pD = dynamic_cast<CDerived *>pB;


When to use?

Consider the scenario below,



Where the CControlIface is an abstract base class with a pure virtual function Draw(). There are two concrete classes implementing the CControlIface interface, CButtonControl and CTextControl which overrides the Draw()'s implementation. Also, they have their own methods


CButtonControl::OnClick()
CTextControl::OnKeyTyped()


The problem is how will we identify the type of object pointed at run-time, if we just have the base class pointer or reference?

The solution is dynamic_casting

Let's look into some code.


CControlIface *pControl1 = new CButtonControl();
CControlIface *pControl2 = new CTextControl();

...
...

ProcessButtonEvent(pControl1);
// No idea what pControl1 points to, at compile time

...
...

void ProcessButtonEvent(CControlIface *pControl)
{
    // Here we need make sure safe down-cast happens
    CButtonControl *pButton = dynamic_cast <CButtonControl *> pControl;

    // casting works fine here since we had passed pControl1

    ...

    if(pButton != NULL)
    {
        pButton->OnClick();
        // We can now safely call OnClick() of CButtonControl
    }
}


What would have happened if we had passed pControl2 while calling ProcessButtonEvent()?

dynamic_cast would have failed since pControl2 is not pointing to CButtonControl's instance. This check is performed by dynamic_cast operator at run-time using RTTI (Run-time Type Information).

Dynamic casting allows us to perform safe type conversions and lets our programs take appropriate actions when such casts fail.

Cheers!

 

Sunday, 17 June 2007

What's "new"?

Today's article talks about the new, which is an essential operator in C++ for dynamically instantiating an object.

Why do we need new operator?
There's a lot of difference between C's malloc and new. It does more than just allocating memory. It also calls the constructor. Which facilitates to initiate the object.

Believe me, operator new and new operator are completely different!
When we instantiate an object
CTest *pObj = new CTest();

This calls global new operator which performs 2 main tasks
1. Call operator new for allocating memory.
2. Call constructor of the particular object.

We can always overload operator new which performs memory allocation operations. But we cannot change the meaning of the global new operator.

Typical example where we overload operator new will be in case of placement new where we change the actual meaning of operator new by passing address of memory where it has to instantiate the object.

Let's talk about placement new in forth coming articles.

Tuesday, 12 June 2007

Conceptual "Virtual Constructors"

In one of my old article I had said that we cannot make the constructors virtual.

But its possible to have Conceptual Conceptual "Virtual Constructors". You might be wondering what do I mean by conceptual here?

Consider following code snippet,


class CAccountIface
{

};

class CSavingsAccount : public CAccountIface
{

};

class CCreditAccount : public CAccountIface
{

};

 


And I have one more class which will have a list of accounts


class CBank
{
    public:
        CAccountIface* CreateAccount(int iAccType);
        std::vector<CAccountIface *> m_Accounts;
}


 Here the member function CAccountIface* CBank:: CreateAccount(int iAccType) acts like a virtual constructor. Depending on the type the user passes either the constructor for CSavingsAccount or CCreditAccount will be called and respective object will be instantiated. This behaves like a virtual constructor.


We can even establish virtualism in case of copy constructors.

Let's try writing a copy c'tor for CBank class.


CBank::CBank(const CBank &AnotherBank)
{

    for(std::vector<CAccountIface *>::size_type i = 0; i < AnotherBank.m_Accounts.size(); ++i )
    {
        this->m_Accounts[i] = AnotherBank.m_Accounts[i]->Clone();
    }
}


I guess u'll already be wondering about the implementation for clone() member function.

Clone() has to be a pure virtual function in CAccountIface, and we can override this in CSavingsAccount and CCreditAccount to clone itself.

So the updated code will be as shown below,


class CAccountIface
{
    public:
        virtual CAccountIface *Clone() = 0;
};

class CSavingsAccount : public CAccountIface
{
    public:
        virtual CSavingsAccount *Clone(){ return new CSavingsAccount(*this);}

};

class CCreditAccount : public CAccountIface
{
    public:
        virtual CCreditAccount *Clone(){ return new CCreditAccount(*this);}

};


When we say


m_Accounts[i]->Clone();


The Clone() function will be called based on the type of object pointed by the pointer m_Accounts[i].

This concept is also referred to as "Factory Pattern"

Saturday, 2 June 2007

Static & Dynamic memory allocations...

I thought of writing this article since it was quite interesting even though it sounds as basic and primitive.

Last night when I was coming back to home on Company's shuttle, my mate Debendra had few C++ questions for me.

He asked "If I create a variable on stack say, int i; and if I say char *p = new char;. When will be the memory gets allocated? What time? Is it run-time or compilation time?"

I had to say "All allocations happen only when you run the program, compiler will just compile the C++ code to instructions which will allocate the memory required on heap/stack"

Then I got an unexpected question from him - "Then why do we say int i; as static allocation and char * p = new char as dynamic allocation, even though all allocations are happening at run-time?"

A crazy question!

Such a primitive and basic doubt every one may get and get confused.

All allocations whether it may be dynamic or static happens at run-time only. But how the allocation is done matters.

Let’s take the static allocation,

int i;

when compiler compiles this code, compiler knows what the size of int is and it knows what number of bytes needs to be allocate at compilation time only. It generates instructions to allocate those many bytes, so that at run-time those many bytes are allocated.

In case of dynamic allocation,

char *p = new char(n);

Compiler wont have any idea what is n, it may be a function parameter or a value evaluated by an expression or even it can be a constant value, but at compilation time it has no idea what may be the number of bytes allocated. This can be dynamically configured and controlled at run-time.

Importantly, in case of dynamic allocation, the amount of memory allocated is determined by the program at the time of allocation and need not be known in advance.

Hence we say this as dynamic allocation.

Hope Debendra had got his doubt cleared.