base.hpp的代码:
#ifndef _H_DYNAMIC_H
#define _H_DYNAMIC_H
#include " Base.h "
#include <iostream>
#include <map>
using namespace std;
template<typename T> Base * createT() { return new T; }
struct BaseFactory {
typedef std::map<std:: string, Base*(*)()> map_type;
static Base * createInstance(std:: string const& s) {
map_type::iterator it = getMap()->find(s);
if(it == getMap()->end())
return 0;
return it->second();
}
protected:
static map_type * getMap() {
if(!map) { map = new map_type; }
return map;
}
public:
static map_type * map;
};
template<typename T>
struct DerivedRegister : BaseFactory {
DerivedRegister(std:: string const& s) {
getMap()->insert(std::make_pair(s, &createT<T>));
cout<< " add "<<endl;
}
};
#define REGISTER_DEC_TYPE(NAME) static DerivedRegister<NAME> reg
#define REGISTER_DEF_TYPE(NAME) DerivedRegister<NAME> NAME::reg(#NAME)
#define _H_DYNAMIC_H
#include " Base.h "
#include <iostream>
#include <map>
using namespace std;
template<typename T> Base * createT() { return new T; }
struct BaseFactory {
typedef std::map<std:: string, Base*(*)()> map_type;
static Base * createInstance(std:: string const& s) {
map_type::iterator it = getMap()->find(s);
if(it == getMap()->end())
return 0;
return it->second();
}
protected:
static map_type * getMap() {
if(!map) { map = new map_type; }
return map;
}
public:
static map_type * map;
};
template<typename T>
struct DerivedRegister : BaseFactory {
DerivedRegister(std:: string const& s) {
getMap()->insert(std::make_pair(s, &createT<T>));
cout<< " add "<<endl;
}
};
#define REGISTER_DEC_TYPE(NAME) static DerivedRegister<NAME> reg
#define REGISTER_DEF_TYPE(NAME) DerivedRegister<NAME> NAME::reg(#NAME)
#endif
Base.h的代码:
#ifndef _H_BASE_H
#define _H_BASE_H
#include <iostream>
using namespace std;
class Base {
string name;
public:
virtual void print();
virtual ~Base();
};
#define _H_BASE_H
#include <iostream>
using namespace std;
class Base {
string name;
public:
virtual void print();
virtual ~Base();
};
#endif
Base.cpp的代码:
#include
"
Base.h
"
Base::~Base(){
cout<< " detructed "<<endl;
}
void Base::print(){
cout<< " base "<<endl;
Base::~Base(){
cout<< " detructed "<<endl;
}
void Base::print(){
cout<< " base "<<endl;
}
derivedb.h的代码:
#include
"
derivedb.hpp
"
DerivedRegister<DerivedB> DerivedB::reg( " DerivedB ");
void DerivedB::print(){
cout<< " derived "<<endl;
DerivedRegister<DerivedB> DerivedB::reg( " DerivedB ");
void DerivedB::print(){
cout<< " derived "<<endl;
}
derivedb.hpp的代码:
#ifndef _H_DERIVEDB_H
#define _H_DERIVEDB_H
#include <iostream>
#include " base.hpp "
#include " Base.h "
using namespace std;
class DerivedB : public Base{
private:
static DerivedRegister<DerivedB> reg;
public :
void print();
};
#define _H_DERIVEDB_H
#include <iostream>
#include " base.hpp "
#include " Base.h "
using namespace std;
class DerivedB : public Base{
private:
static DerivedRegister<DerivedB> reg;
public :
void print();
};
#endif
main的测试代码:
#include
"
Animal.h
"
#include " Cat.h "
#include <iostream>
#include " base.hpp "
#include <dlfcn.h>
#include " derivedb.hpp "
#include <map>
using namespace std;
BaseFactory::map_type * BaseFactory::map;
class Base;
void load(){
void *handle = dlopen( " ./deriveb.so ",RTLD_NOW|RTLD_GLOBAL);
if(!handle)
{
std::cerr << dlerror() << std::endl;
return;
}
else{
cout<< " load OK "<<endl;
}
Base * bp = BaseFactory::createInstance( " DerivedB ");
bp->print();
}
using namespace std;
int main( int argc, char ** argv ){
load();
return 0;
#include " Cat.h "
#include <iostream>
#include " base.hpp "
#include <dlfcn.h>
#include " derivedb.hpp "
#include <map>
using namespace std;
BaseFactory::map_type * BaseFactory::map;
class Base;
void load(){
void *handle = dlopen( " ./deriveb.so ",RTLD_NOW|RTLD_GLOBAL);
if(!handle)
{
std::cerr << dlerror() << std::endl;
return;
}
else{
cout<< " load OK "<<endl;
}
Base * bp = BaseFactory::createInstance( " DerivedB ");
bp->print();
}
using namespace std;
int main( int argc, char ** argv ){
load();
return 0;
}
编译:
g++ -fPIC -shared -o deriveb.so derivedb.cpp
g++ -c Base.cpp
g++
-rdynamic -g -ldl main.cpp Base.o
这里有一个非常关键的地方,就是这个-rdynamic,如果不加这个选项,dlopen会包undifined symbol,参考:http://stackoverflow.com/questions/480617/dlopen-issue