views:

75

answers:

1

I was reading about static and dynamic libraries. To explore more I created three files 2 .cpp files and 1 .h file

demo.h

 class demo
{

    int a;

    public:

    demo();
    demo(const demo&);
    demo& operator=(const demo&);
   ~demo();
};

demo.cpp

#include "demo.h"
#include <iostream>
demo::demo():a()
{
    std::cout<<"\nInside default constructor\n";
}

demo::demo(const demo&k)
{

    this->a=k.a;
    std::cout<<"\nInside copy constructor\n";
}

demo& demo::operator=(const demo&k)
{
    this->a=k.a;
    std::cout<<"\nInside copy assignment operator\n";
    return *this;
}

demo::~demo()
{
    std::cout<<"\nInside destructor\n";
}

main.cpp

#include "demo.h"

int main()
{

   demo d;
   demo d1=d;
   demo d2;
   d2=d;
}

Now I created two object files :demo.o and main.o using g++ -c demo.cpp and g++ -c main.cpp and then created a static library using ar cr demo.a demo.o main.o

I also created a dynamic library using g++ -shared demo.o main.o -o demo.dll

Now when I use my static library(g++ demo.a -o demo) to create an executable everything goes fine. But when I use my dynamic library to create an executable I get an error Undefined reference to main I have used the following command to create an executable g++ demo.dll -o demo.

When I use g++ main.cpp -o demo demo.dll everything goes fine, why?

Where am I wrong?

+1  A: 

When compiling code for a .so (or .dll as you call it) that code needs to be position independent. Man gcc:

   -shared
       Produce a shared object which can then be linked with other objects
       to form an executable.  Not all systems support this option.  For
       predictable results, you must also specify the same set of options
       that were used to generate code (-fpic, -fPIC, or model suboptions)
       when you specify this option.

   ...

   -fpic
       Generate position-independent code (PIC) suitable for use in a
       shared library, if supported for the target machine.  Such code
       accesses all constant addresses through a global offset table
       (GOT).  The dynamic loader resolves the GOT entries when the
       program starts (the dynamic loader is not part of GCC; it is part
       of the operating system).  If the GOT size for the linked
       executable exceeds a machine-specific maximum size, you get an
       error message from the linker indicating that -fpic does not work;
       in that case, recompile with -fPIC instead.  (These maximums are 8k
       on the SPARC and 32k on the m68k and RS/6000.  The 386 has no such
       limit.)

       Position-independent code requires special support, and therefore
       works only on certain machines.  For the 386, GCC supports PIC for
       System V but not for the Sun 386i.  Code generated for the IBM
       RS/6000 is always position-independent.

       When this flag is set, the macros "__pic__" and "__PIC__" are
       defined to 1.

In other words:

g++ -o main.o -c -fpic main.cpp
g++ -o demo.o -c -fpic demo.cpp
g++ -o demo.dll -shared main.o demo.o
g++ -o demo demo.dll
Maxim Yegorushkin