Dynamic class loading

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • vlbel@mail.ru

    #1

    Dynamic class loading

    I'm trying to do the following:

    1) The main program consists of
    ------------ a.h ------------
    class A
    {
    public:
    virtual ~A(){}
    virtual void b();
    };

    ------------ a.cpp -----------
    #include "a.h"

    void A::b()
    {}

    ------------ main.cpp ------------
    #include <dlfcn.h>
    #include <iostream>
    using namespace std;

    int main()
    {
    void* handler = dlopen( "../lib/lib.so", RTLD_LAZY );
    if( !handler )
    {
    cout << "Bad" << endl;
    cout << dlerror() << endl;
    }
    }
    -----------------------------------

    2) Loadable library:

    ---------------- lib.cpp --------------------
    #include "a.h"

    class C : public A
    {
    public:
    C() : A(){}
    };


    extern "C" A* maker()
    {
    return new C();
    }
    ----------------------------------------------

    Compiles ok (gcc 4.1.0, SUSE Linux), but running the program I get:
    .../lib/lib.so: undefined symbol: _ZN1A1bEv

    What's the matter? nm shows that symbol is defined (in a.o)
  • Victor Bazarov

    #2
    Re: Dynamic class loading

    vlbel@mail.ru wrote:
    I'm trying to do the following:
    >
    1) The main program consists of
    ------------ a.h ------------
    class A
    {
    public:
    virtual ~A(){}
    virtual void b();
    };
    >
    ------------ a.cpp -----------
    #include "a.h"
    >
    void A::b()
    {}
    >
    ------------ main.cpp ------------
    #include <dlfcn.h>
    #include <iostream>
    using namespace std;
    >
    int main()
    {
    void* handler = dlopen( "../lib/lib.so", RTLD_LAZY );
    if( !handler )
    {
    cout << "Bad" << endl;
    cout << dlerror() << endl;
    Neither 'dlopen' nor 'dlerror' are standard C++ or C functions.
    They aren't topical here (if you think they are essential to
    your question, which I believe they are).
    }
    }
    -----------------------------------
    >
    2) Loadable library:
    >
    ---------------- lib.cpp --------------------
    #include "a.h"
    >
    class C : public A
    {
    public:
    C() : A(){}
    };
    >
    >
    extern "C" A* maker()
    {
    return new C();
    }
    ----------------------------------------------
    >
    Compiles ok (gcc 4.1.0, SUSE Linux), but running the program I get:
    ../lib/lib.so: undefined symbol: _ZN1A1bEv
    >
    What's the matter? nm shows that symbol is defined (in a.o)
    Your question has no answer in terms of C++ _langauge_. You need to
    ask in the newsgroup where dynamic linking is on topic (most likely
    the newsgroup for your OS). Also, since you're using 'gcc' you might
    consider posting to 'gnu.g++.help' or 'gnu.gcc.help' since they know
    more about how the compiler/linker resolves symbols in such cases.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask


    Comment

    • Peter

      #3
      Re: Dynamic class loading

      On Nov 26, 2:18 am, vl...@mail.ru wrote:
      I'm trying to do the following:
      you may want to make A an abstract class -- there is no need for an
      a.cpp:

      class A
      {
      public:
      virtual ~A(){}
      virtual void b() = 0;
      };


      a certain compiler version of gcc forbids that the executable exports
      symbols.
      You need to link your executable with the option -rdynamic to make it
      export symbols.
      Or you can make certain that the executable does not need to export
      any symbols by putting everything required into another shared
      library. The advantage being that the same library structure would
      also work on Windows where you cannot export symbols from an
      executable at all.
      Also -- I would wrap dlopen()/dlclose() into a C++ resource wrapper
      (
      calling dlopen() in the constructor and dlclose() in the destructor --
      the constructor should throw something derived from std::exception
      which contains all error information -- e.g. what has been returned
      from dlerror().
      In general you should do this with every C-style resource you
      encounter. If there is a do-action and an undo-action wrap it into a C+
      + class which throws on error.
      )

      Comment

      Working...