Quote:
Originally posted by Mara
If you want to load the library dynamically, use dlopen/dlsym calls, don't link with the lib. You don't need header file when using this way.
|
look at this example which you can use as a base:
//-------------Base.h
// this is were the abstract interface is defined
Code:
#ifndef __PE_H
#define __PE_H
#include <iostream>
using namespace std;
struct Base {
public:
Base() { cout << "Building Base "<< endl; };
virtual ~Base() { cout << "Destroying Base "<< endl; };
virtual void Do() = 0;
virtual void Put(double a) = 0;
};
// the types of the class factories
typedef Base* Create_t();
typedef void Destroy_t(Base*);
#endif
//------------------ example.h
// example.h and example.cpp is a plugin that implements the Base abstract class.
Code:
#include <iostream>
using namespace std;
#include "base.h"
struct iExample : public Base
{
iExample()
{
cout << "initializing iExample "<< endl;
};
virtual ~iExample()
{
cout <<" destroying iExample "<< endl;
};
double somedata;
virtual void Do();
virtual void Put(double a);
};
//------------- example.cpp
Code:
#include "example.h"
void iExample :: Do() { cout << somedata << endl; }
void iExample :: Put(double a) { somedata = a; }
// the class factories
extern "C" Base* Create() {
return new iExample;
}
extern "C" void Destroy(Base* p) {
delete p;
}
To compile the 'example' plugin you need to do:
g++ -fPIC -c example.cpp
g++ -shared -o libexample.so example.o
//---------------- plug_test.cpp
// this is a test application where you load the plugin and use it.
// Note that this requires the base.h header to compile
Code:
#include "base.h"
#include <iostream>
#include <dlfcn.h>
using namespace std;
int main()
{
// load the iExample plugin
cout << "loading " << endl;
void* example = dlopen("./libexample.so", RTLD_LAZY);
if (!example) {
cerr << "Cannot load library: " << dlerror() << '\n';
return 1;
}
cout << " done " << endl;
// load the symbols
Create_t* create_example = (Create_t*) dlsym(example, "Create");
Destroy_t* destroy_example = (Destroy_t*) dlsym(example, "Destroy");
if (!create_example || !destroy_example) {
cerr << "Cannot load symbols: " << dlerror() << '\n';
return 1;
}
cout << "symbols loaded " << endl;
// create an instance of the class
Base* poly = create_example();
// use the class
poly->Put(7);
poly->Do();
// destroy the class
destroy_example(poly);
// unload the iExample plugin Factory
dlclose(example);
};
executable compilation:
g++ -c plug_test.cpp
g++ -rdynamic -ldl -Wall plug_test.o -o plug_test.x
Note also, that is possible to extract the symbols in a plugin library and reconstruct a header file, but this is only needed when the actual header file was lost. In most circumstances you won't need to do that. If that's what u need, there is a command to dump the symbols inside a shared object but i don't remember (anyone?) after that, you will need to demangle each symbol with c++filt. With that information you have all you need to reconstruct a lost header