LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Dynamic Class Loading Problems (https://www.linuxquestions.org/questions/programming-9/dynamic-class-loading-problems-205570/)

dmnc 07-15-2004 06:53 PM

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

Galik 07-15-2004 08:10 PM

I think your link instruction forgets to include the shared library you built.

Try
Code:

g++ -o main -ldl main.o plugin.so

Hano 07-15-2004 11:05 PM

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

dmnc 07-16-2004 06:06 AM

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)

Hano 07-16-2004 10:37 AM

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

dmnc 07-18-2004 04:08 PM

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

Hano 07-19-2004 02:02 PM

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

dmnc 07-20-2004 01:35 PM

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

Hano 07-22-2004 12:13 AM

this is very weird. what g++ version you have?

dmnc 07-22-2004 01:21 PM

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

Hano 07-22-2004 02:42 PM

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)


Hano 07-22-2004 04:06 PM

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.


All times are GMT -5. The time now is 04:30 PM.