本文介绍将会介绍 QT 源码之 QLibrary 跨平台调用动态库实现,在内容中,将会讨论Qt是如何封装这两种不同的调用动态库的方法。先看内容。

详解 QT 源码之 QLibrary 跨平台调用动态库实现是本文要讲解的内容,在不同同台上动态库的使用,先来看内容。

详解 QT 源码之 QLibrary 跨平台调用动态库实现(qt开发动态库)  动态库 第1张

1、win下动态库调用有关的函数包括:

(1)LoadLibrary,装载动态库

(2)GetProcAddress,获取要引入的函数,将符号名或标识号转换为DLL内部地址。

(3)FreeLibrary,释放动态链接库。

2、unix上与动态库调用有关的函数包括:

(1)_打开动态链接库:dlopen,函数原型void *dlopen (const char *filename, int flag);

dlopen用于打开指定名字(filename)的动态链接库,并返回操作句柄。

(2)取函数执行地址:dlsym,函数原型为: void *dlsym(void *handle, char *symbol);

dlsym根据动态链接库操作句柄(handle)与符号(symbol),返回符号对应的函数的执行代码地址。

(3)关闭动态链接库:dlclose,函数原型为: int dlclose (void *handle);

dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。

(4)动态库错误函数:dlerror,函数原型为: const char *dlerror(void); 当动态链接库操作函数执行失败时,dlerror可以返回出错信息,返回值为NULL时表示操作函数执行成功。

我们来分析下Qt的源代码,看看Qt是如何封装这两种不同的调用动态库的方法。

下面是我用vc编写的一个动态库中的函数add:

  1. extern"C"__declspec(dllexport)int__stdcalladd(inta,intb)
  2. {
  3. returna+b;
  4. }

下面我就用QLibrary来调用一下:

  1. QLibrarylib("QtDllTest.dll");
  2. if(lib.load())
  3. {
  4. typedefint(*AddFunction)(inta,intb);
  5. AddFunctionAdd=(AddFunction)lib.resolve("add");
  6. if(!Add)
  7. {
  8. cout<<"failed"<<endl;
  9. }
  10. else
  11. {
  12. intm;
  13. m=Add(1,1);//来个计算1+1
  14. cout<<"result:"<<m<<endl;
  15. }
  16. lib.unload();
  17. }
  18. else
  19. {
  20. cout<<"failed"<<endl;
  21. }

首先将目录切换到QTDIR\src\corelib\plugin,这里面就是QLibrary实现的源代码,打开QLibrary_p.h(熟悉了Qt的常用手法,就知道,这就是QLibrary内部实现的代码),可以看到

  1. boolload_sys();
  2. boolunload_sys();
  3. void*resolve_sys(constchar*);

三个函数。在qlibrary.cpp中可以找到调用这三个函数的地方

  1. boolQLibrary::load()调用了load_sys;
  2. boolQLibrary::unload()调用了unload_sys;
  3. void*QLibrary::resolve(constchar*symbol)调用了resolve_sys

但是并没有找到这三个函数的实现,这是这么回事呢?

打开QTDIR\src\corelib\plugin\plugin.pri文件,

  1. win32{
  2. SOURCES+=plugin/qlibrary_win.cpp
  3. }
  4. unix{
  5. SOURCES+=plugin/qlibrary_unix.cpp
  6. }

原来如此啊。

我们仔细看下qlibrary_win.cpp文件,load_sys函数调用了LoadLibrary,unload_sys调用了FreeLibrary,resolve_sys调用了GetProcAddress。

而在qlibrary_unix.cpp文件中,各种linux平台又分好多种。但是基本上load_sys调用了dlopen,unload_sys调用了dlclose,resolve_sys调用了dlsym。

在HPUX中dlopen对应shl_load,dlclose对应shl_unload,dlsym对应shl_findsym。

原来QLibrary就是这样实现不同平台动态库的调用。

小结:详解 QT 源码之 QLibrary 跨平台调用动态库实现的内容介绍完了,希望本篇文章对你有所帮助!

转载请说明出处
知优网 » 详解 QT 源码之 QLibrary 跨平台调用动态库实现(qt开发动态库)

发表评论

您需要后才能发表评论