Forum

> > Off Topic > Loading classes from a library
Forums overviewOff Topic overviewLog in to reply

English Loading classes from a library

2 replies
To the start Previous 1 Next To the start

old Loading classes from a library

Wolf6331
User Off Offline

Quote
Hey guys!

I have a problem with loading classes from a lib ( for win32 and linux ) at runtime.

That's my code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/*
Exectuable source -- file: main.cpp
*/

#include <iostream>
#include <fstream>
#include <string>

#include <dlfcn.h>

using namespace std;

class CBase
{
  protected:
    int x;
    int y;
  public:
    virtual ~CBase( void ) = 0;
    virtual void add ( int _x, int _y ) = 0;
    virtual void move ( int _x, int _y ) = 0;
    virtual void print ( void ) = 0;
};

int main()
{
    ifstream f;
    f.open ( "class.txt" );

    if ( f == NULL )
    {
        cout << "No \"class.txt\" file found!" << endl;
        return -1;
    }

    string classname = "EMPTY";
    f >> classname;
    f.close();

    void * sofile = NULL;
    sofile = dlopen ( "./libC.so", RTLD_LAZY );
    if ( sofile == NULL )
    {
         cout << "ERROR!(1) -> " << dlerror() << endl;
         return -1;
    }

     typedef CBase * ( * new_class ) ( void );
     typedef void ( * delete_class ) ( CBase * );

     new_class cbase_new = NULL;
     delete_class cbase_delete = NULL;

     string str = classname + "_new";
     cbase_new = (new_class) dlsym ( sofile, str.c_str() );
     str = classname + "_delete";
     cbase_delete = (delete_class) dlsym ( sofile, str.c_str() );

     if ( cbase_new == NULL || cbase_delete == NULL )
     {
         cout << "ERROR! -> " << dlerror() << endl;
         dlclose( sofile );
         return -1;
     }

     CBase * t = cbase_new();

     if ( t != NULL )
     {
         t->add( 2, 4 );
         t->print();
         t->move( 4, 10 );
         t->print();
     }

     cbase_delete ( t );

     dlclose( sofile );

     return 0;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/*
Lib source -- file: c.cpp
*/

#include <iostream>

class CBase
{
  protected:
    int x;
    int y;
  public:
    virtual ~CBase( void ) = 0;
    virtual void add ( int _x, int _y ) = 0;
    virtual void move ( int _x, int _y ) = 0;
    virtual void print ( void ) = 0;
};

class CTest : public CBase
{
  public:
    void add ( int _x, int _y );
    void move ( int _x, int _y );
    void print ( void );
};

void CTest::add ( int _x, int _y )
{
    x = _x;
    y = _y;
}

void CTest::move ( int _x, int _y )
{
    x += _x;
    y += _y;
}

void CTest::print ( void )
{
    std::cout << "X: " << x << std::endl;
    std::cout << "Y: " << y << std::endl;
}

extern "C"
{
    CBase * ctest_new ( void )
    {
        return new CTest;
    }

    void ctest_delete ( CBase * p )
    {
        delete p;
    }
}

I only did it on linux for testing. That's why i have no defines/functions for windows.

This is the console output:
1
2
./ClassFromLib
ERROR!(1) -> ./libC.so: undefined symbol: _ZN5CBaseD2Ev

C++ saves symbols of functions and structures in a different way into a lib than C.
I do not know, why it can't load this class : (
can someone help me ?

old Re: Loading classes from a library

Lee
Moderator Off Offline

Quote
You have a bit more to worry about than just this, but to solve your immediate problem:

_ZN5CBaseD#Ev

_ZN5 is a name dmangling prefix, Ev gives clues to return type and parameters

CBase is the name of your class
D is the qualified identifier for destructor.

This means that your CBase::~CBase is at fault. Looking back at your code:

1
2
3
public:
	~CBase(void) = 0;
	...


This is a big no-no. To write a opaque virtual destructor, use the following notation:

1
2
3
public:
	~CBase(void){};
	...

PS: using the -shared flag with gcc prevents ar, so errors regarding virtual lookups and references are silenced.
To the start Previous 1 Next To the start
Log in to replyOff Topic overviewForums overview