为了提升程序的复用性,很多时候我们需要通过动态库模块来扩展程序。这里就介绍一下如何通过Poco库动态的挂载和解析动态库文件。
1.解析动态库中的导出函数
//解析动态库函数
void ParserSharedLibrary()
{
//设置库的名称和后缀
std::string path = "TestLibrary";
path.append(SharedLibrary::suffix());
//声明函数指针
typedef int (*myFunc)();
try
{
//加载动态库
SharedLibrary sl;
sl.load(path);
//判断符号是否存在
if(sl.hasSymbol("myFunc"))
{
//获取函数并调用
myFunc p1 = (myFunc)sl.getSymbol("myFunc");
p1();
}
}
//解析异常
catch(NotFoundException& e)
{
cout << "not find the symbol" << std::endl;
}
//加载异常
catch(LibraryLoadException& e)
{
cout << "load dll error" << std::endl;
}
//卸载动态库
sl.unload();
}
2.解析动态库中的导出类
//解析动态库中的类信息
class TestPlugin
{
public:
TestPlugin();
virtual ~TestPlugin();
virtual std::string name() const = 0;
};
void classLoader()
{
//指定动态库的路径
std::string path = "TestLibrary";
path.append(SharedLibrary::suffix());
try
{
//加载动态库
ClassLoader<TestPlugin> loader;
loader.loadLibrary(path);
//查找某个类的元对象引用
const ClassLoader<TestPlugin>::Meta& POCO_UNUSED meta = loader.classFor("PluginA");
//析构的时候自动删除实例对象
meta2.autoDelete(meta2.create());
//获取符号表
const ClassLoader<TestPlugin>::Manif& POCO_UNUSED manif = loader.manifestFor(path);
//创建某个类的实例
TestPlugin* pPluginA = loader.classFor("PluginA").create();
TestPlugin* pPluginB = loader.create("PluginB");
TestPlugin& pluginC = loader.instance("PluginC");
}
catch(NotFoundException& e)
{
//符号找不到异常
}
catch (InvalidAccessException& e)
{
//不合理访问异常
}
//卸载动态库
loader.unloadLibrary(path);
}
3.使用动态库的Manifest信息
//类符号表的用法
class MfTestBase
{
};
void Manifest()
{
Manifest<MfTestBase> manifest;
//插入新元素
manifest.insert(new MetaObject<MfTestObject, MfTestBase>("MfTestObject1"));
//查找某个元素
assertTrue (manifest.find("MfTestObject1") != manifest.end());
std::set<std::string> classes;
//通过迭代器遍历寻找
Manifest<MfTestBase>::Iterator it = manifest.begin();
assertTrue (it != manifest.end());
classes.insert(it->name());
++it;
//清空符号列表
manifest.clear();
}