LinuxQuestions.org
Did you know LQ has a Linux Hardware Compatibility List?
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices



Reply
 
Search this Thread
Old 07-15-2004, 07:53 PM   #1
dmnc
LQ Newbie
 
Registered: Jul 2004
Posts: 5

Rep: Reputation: 0
Dynamic Class Loading Problems


Hello,

I'm trying to use dynamic class loading to implement a plugin in c++ (i have g++ 3.3.1).
I have two classes, 'base' class and 'derivada1' class (inherit 'base' class). 'derivada1' class implements 'base' class (method f1) and add a new method (method f2).
Compiler doesn't have any problem, but linker generate two error messages:

In function 'main': undefined reference to 'typeinfo' for derivada1

In function 'main': undefined reference to 'derivada1::f2 ()'

What's the problem? Have i a concept errors? In the following lines i adjunt my files.

Thank in advance.

dmnc

----------------------------------------------
base.h

#ifndef _BASE_H
#define _BASE_H

class base
{
public:
virtual void f1 () = 0;
};

#endif
----------------------------------------------
derivada.h:

#include "base.h"
#include <stdio.h>


class derivada1 : public base
{
public:
void f1 ();
void f2 ();
};
----------------------------------------------
derivada.cpp

#include "derivada.h"

void derivada1::f1 ()
{
printf ("f1 - derivada1\n");
}

void derivada1::f2 ()
{
printf ("f2 - derivada1\n");
}

extern "C"
{
base* factoria ()
{
return new derivada1;
}
}
----------------------------------------------
main.cpp

#include <dlfcn.h>
#include <iostream>

#include "derivada.h"

using namespace std;

int main ()
{
void *hndl = dlopen("./prova.so", RTLD_LAZY);
if(hndl == NULL)
{
cerr << dlerror() << endl;
exit(-1);
}

void * mkr = dlsym (hndl, "factoria");
base * b = ((base*(*)())(mkr))();;
derivada1 * d = dynamic_cast <derivada1*> (b);
d->f1 ();
d->f2 ();
}
----------------------------------------------
Simple Makefile:

all:
g++ -shared -o plugin.so -c derivada.cpp
g++ -c main.cpp
g++ -o main main.o -ldl
 
Old 07-15-2004, 09:10 PM   #2
Galik
Member
 
Registered: Mar 2003
Location: UK
Distribution: gentoo
Posts: 67

Rep: Reputation: 15
I think your link instruction forgets to include the shared library you built.

Try
Code:
g++ -o main -ldl main.o plugin.so
 
Old 07-16-2004, 12:05 AM   #3
Hano
Member
 
Registered: Sep 2001
Location: Venezuela, Caracas
Distribution: RedHat 9.0
Posts: 196

Rep: Reputation: 30
plugin compilation:

g++ -fPIC -c derivada.cpp <--- without fPIC you wont get a valid shared library!!
g++ -shared -o derivada.so derivada.o

executable compilation:
g++ -c main.cpp
g++ -rdynamic -ldl -Wall main.o -o main.x


cheers
 
Old 07-16-2004, 07:06 AM   #4
dmnc
LQ Newbie
 
Registered: Jul 2004
Posts: 5

Original Poster
Rep: Reputation: 0
Hello

Solution 1) g++ -o main main.o -ldl main.o plugin.so
I'll try to use dynamic load class so i supose that i can't put plugin.so. I supose that if i use dynamic load class, unresolved references are resolved in run-time not in linker time. Is it correct?

Solution 2) g++ -fPIC -c derivada.cpp
g++ -shared -o plugin.so derivada.o
g++ -c main.cpp
g++ -rdynamic -ldl -Wall main.o plugin.so -o main

I used this senteces to compile and linker but linker showed the same errors.

dmnc



2)
 
Old 07-16-2004, 11:37 AM   #5
Hano
Member
 
Registered: Sep 2001
Location: Venezuela, Caracas
Distribution: RedHat 9.0
Posts: 196

Rep: Reputation: 30
Quote:
Solution 2) g++ -fPIC -c derivada.cpp
g++ -shared -o plugin.so derivada.o
g++ -c main.cpp
g++ -rdynamic -ldl -Wall main.o plugin.so -o main

I used this senteces to compile and linker but linker showed the same errors.

no wonder. that was NOT what i tell you to use; read it again
 
Old 07-18-2004, 05:08 PM   #6
dmnc
LQ Newbie
 
Registered: Jul 2004
Posts: 5

Original Poster
Rep: Reputation: 0
I used:
all:
g++ -c derivada.cpp
g++ -shared -o plugin.so derivada.o
g++ -c main.cpp
g++ -rdynamic -ldl -Wall main.o -o main

and linker showed the same errors.

Any suggestion ??

Thanks

dmnc
 
Old 07-19-2004, 03:02 PM   #7
Hano
Member
 
Registered: Sep 2001
Location: Venezuela, Caracas
Distribution: RedHat 9.0
Posts: 196

Rep: Reputation: 30
what about what i posted originall?

Quote:
hano said:
plugin compilation:

g++ -fPIC -c derivada.cpp <--- without fPIC you wont get a valid shared library!!
g++ -shared -o derivada.so derivada.o
compare it with

Quote:
dmnc said:
g++ -c derivada.cpp
g++ -shared -o plugin.so derivada.o
your main executable has correct options (in your last post only)



cheers
 
Old 07-20-2004, 02:35 PM   #8
dmnc
LQ Newbie
 
Registered: Jul 2004
Posts: 5

Original Poster
Rep: Reputation: 0
Hello again,

This time i used this senteces:
g++ -c derivada.cpp
g++ -shared -o derivada.so derivada.o
g++ -c main.cpp
g++ -rdynamic -ldl -Wall main.o -o main

but linker showed same error.

Error:
main.o(.text+0xa1): In function `main':
: undefined reference to `derivada1::f2()'
collect2: ld returned 1 exit status
make: *** [all] Error 1


Any suggestions ?

Thanks again
dmnc
 
Old 07-22-2004, 01:13 AM   #9
Hano
Member
 
Registered: Sep 2001
Location: Venezuela, Caracas
Distribution: RedHat 9.0
Posts: 196

Rep: Reputation: 30
this is very weird. what g++ version you have?
 
Old 07-22-2004, 02:21 PM   #10
dmnc
LQ Newbie
 
Registered: Jul 2004
Posts: 5

Original Poster
Rep: Reputation: 0
Hello,


I use g++ 3.3.1 under SUSE 9.0.

I think, there are two situacion using dynamic class loading technique.

First situacion:
We have two classes, a "base" class and "derivada" class. The second class inherit from the first class and only implements two virtual methods (f1, and f2) which are declared in "base" class. This two classes are included in a library called derivada.so
In this case we don't have any problem to load derivada library(dlopen), create a "derivada" object and call this methods (f1 and f2).
Code:
class base
{
public:
virtual void f1 ()=0;
virtual void f2 ()=0;
}
class derivada : public base
{
public:
void f1 ();
void f2 ();
}


Second situacion (in this situacion i have the problem):
We have two classes, a "base" class ( it has one method and this method (f1) is virtual) and "derivada" class. The second class inherit from the first class. This class implements the virtual method and add a new method(f2) which doesn't exist in base class (extend base class). This two classes are included in a libray called derivada.so
In this case we don't have any problem to load derivada library (dlopen), create a "derivada" objecte and call f1 method . But when you call f2 method linker show this message:
main.o(.text+0x99): In function `main':
: undefined reference to `derivada::f2()'
collect2: ld returned 1 exit status
make: *** [all] Error 1

Code:
class base
{
public:
virtual void f1 ()=0;
}
class derivada : public base
{
public:
void f1 ();
void f2 ();
}

This is correct ?

dmnc
 
Old 07-22-2004, 03:42 PM   #11
Hano
Member
 
Registered: Sep 2001
Location: Venezuela, Caracas
Distribution: RedHat 9.0
Posts: 196

Rep: Reputation: 30
ah well any method not present as virtual in the base class will not be of use for the polymorphic plugin. remember that in the main application you store a pointer of the plugin as the base class

of course f2 can be still of use to f1 as a private method of the derived plugin, but no as a directly accesable method to the user (in this case, the main application)


Last edited by Hano; 07-22-2004 at 03:44 PM.
 
Old 07-22-2004, 05:06 PM   #12
Hano
Member
 
Registered: Sep 2001
Location: Venezuela, Caracas
Distribution: RedHat 9.0
Posts: 196

Rep: Reputation: 30
one observation about your main application:

Code:
#include <dlfcn.h>
#include <iostream>

#include "derivada.h"

using namespace std;

int main ()
{
void *hndl = dlopen("./prova.so", RTLD_LAZY);
if(hndl == NULL)
{
cerr << dlerror() << endl;
exit(-1);
}

A  void * mkr = dlsym (hndl, "factoria");
B   base * b = ((base*(*)())(mkr))();;
C   derivada1 * d = dynamic_cast <derivada1*> (b);
D   d->f1 ();
E   d->f2 ();
}
you dont include base.h.. without this you cannot use the pointer on line B. this shouldnt compile! btw you dont have to include derivada.h, only the base class


anyway, i havent tested myself, but probably if you have the header file of the plugin you can (at the cost of recompiling the main application) use a derivada * pointer at line B to hold the plugin instance instead of the base class. In this case, the derivada "should" be the new "base class", meaning that it can define new virtual methods, but im not sure if this would work.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
dynamic class loading doesn't find my functions!? Thinking Programming 1 07-28-2005 03:12 PM
dynamic class instantiation in c++? Thinking Programming 3 07-28-2005 09:59 AM
problem on dynamic function call inside a class! antony_csf Programming 0 06-29-2004 11:15 PM
Error loading class message generated by applet BobBuchanan Programming 0 06-27-2004 05:39 PM
dynamic array in class help PTBmilo Programming 6 03-09-2003 03:35 AM


All times are GMT -5. The time now is 02:35 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration