关于使用QLibrary如何读取共享库

现在程序讲究个模块化,插件化,所有共享库的读取变的尤其关键,把程序写成各种各样的共享库,那升级的时候只需要重写下某个库,在保证头文件不变的情况下,更新上去,就能完美运行。Qt中读取使用共享库的类叫QLibrary. 使用起来也相当简单,最基本的使用只需要知道4个函数,load(), isLoad(), revovle()和unload().在绝大部分情况下,下面这四个函数就足够完成工作了。下面是个小例子:

[cpp]  view plain copy
  1. // 库名是mylib.so,这个文件后缀可以不加  
  2. // Qt会根据操作系统自动添加后缀  
  3. QLibrary lib("mylib");  
  4.   
  5. // 这是最重要的地方,根据你要调用的库函数先定义一个相同的函数指针  
  6. typedef (MyType *)(InstanceOf)();  
  7.   
  8. // instanceOf是你要读取的库中的函数名字  
  9.   
  10. InstanceOf instance = (InstanceOf)lib.revolve("instanceOf");  
  11.   
  12. // revolve成功则运行函数  
  13. // 不成功则输出错误字符串  
  14. if(instance)  
  15.     MyType *ret = instance();  
  16. else  
  17.     qDebug() << lib.errorString();  

这里并没有使用到load()函数,这是因为revolve()函数会自动去加载库,同时Qt还给出了一个简单的static函数来读取库中的函数:

[cpp]  view plain copy
  1. typedef (MyType *)(InstanceOf)();  
  2.   
  3. InstanceOf instance = QLibrary::revolve("mylib","instanceOf");  
  4.   
  5. if(instance)  
  6.     MyType *ret = instance();  

最后要着重说明的就是,QLibrary只能读取共享库内的C函数,这是因为C++为了达到面向对象编程封装,继承,多态等特性,实际的symbol table和你定义的是不同的,他会在编译过程中加入一些字符,比如上例中的instanceOf函数,在symbol table中可能是"_ZV12instanceOf4FR"这样的存在,所以如果把该函数声明为简单的类函数,QLibrary是找不到的,必须要将你准备让QLibrary读的函数声明为C函数,如下

[cpp]  view plain copy
  1. extern "C" MyType *instanceOf()  
  2. {  
  3.     return new MyType();  
  4. }  

这个函数返回MyType的一个对象,这样,只要你有相应的头文件,就可以完全使用这个对象内的其他类函数了。


这个instanOf函数必须定义在cpp文件中,如果写在.h文件中,在生成库的时候会报多重声明的错误, 这原因我觉得有可能是因为Qt的MOC编译器通过.h文件生成一个新的moc_*.cpp,之后在GCC上编译库的时候会使用到原始的.h,.cpp和这个生成的moc.cpp,这个instanOf同时出现在原始的.h和生成的moc.cpp中就重复定义了。

你可能感兴趣的:(关于使用QLibrary如何读取共享库)