I'm trying to dynamically load libraries that implement a base class, defined in another library. I've followed instructions depicted here:
http://www.linuxjournal.com/article/3687?page=0,1
I created a shape class and put it in a separated library (not a real library since its just a header file, but put it that way), also I created two dynamic libraries, circle and square, that inherit from shape and implement the draw method and register their maker function in the factory map. Let me show you the code:
shape.h:
#ifndef __SHAPE_H
#define __SHAPE_H
#include <map>
#include <string>
// base class for all shapes
class shape{
public:
// our global factory
virtual void draw()=0;
};
// typedef to make it easier to set up our factory
typedef shape *maker_t();
extern std::map<std::string, maker_t *, std::less<std::string> > factory;
#endif // __SHAPE_H
circle.h
#ifndef __CIRCLE_H
#define __CIRCLE_H
#include "shape.h"
class circle : public shape
{
public:
void draw();
};
#endif // __CIRCLE_H
circle.cpp:
#include <iostream>
#include "circle.h"
void circle::draw()
{
// simple ascii square
std::cout << "\n";
std::cout << " ****\n";
std::cout << " * *\n";
std::cout << " * *\n";
std::cout << " * *\n";
std::cout << " * *\n";
std::cout << " * *\n";
std::cout << " ****\n";
std::cout << "\n";
}
extern "C"
{
shape *maker()
{
return new circle;
}
class proxy
{
public:
proxy()
{
// register the maker with the factory
factory["circle"] = maker;
}
};
// our one instance of the proxy
proxy circle_p;
}
I won't go into the square, since it's almost identical to the circle neither the actual "client" that dynamically loads the libraries, since it actually works.
Now my question is, in case you have other classes and functionality in the circle.so (this is my case), and in some cases you need link at compile time (-l option), I run into problems. I created a test client library that instead of dynamically loading circle, it does it at compile time. Linker fails with the following output:
Invoking: GCC C++ Linker
g++ -rdynamic -L/home/lizardking/workspace/dynclientest/Debug/libs -o "test2" ./src/test2.o -ldynlib_circle
/home/lizardking/workspace/dynclientest/Debug/libs/libdynlib_circle.so: undefined reference to `factory'
collect2: ld returned 1 exit status
The main.cpp from this test app is just a hello world!:
#include <iostream>
using namespace std;
int main() {
cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
return 0;
}
I really dunno why the linker is complaining all the time about the map....any ideas???
Thanks!