详解 QT 源码之 QLibrary 跨平台调用动态库实现
创始人
2024-08-01 14:11:47
0

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

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 __stdcall add(int a,int b)  
  2. {  
  3.     return a+b;  

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

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

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

  1. bool load_sys();  
  2. bool unload_sys();  
  3. void *resolve_sys(const char *); 

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

  1. bool QLibrary::load ()调用了load_sys;  
  2. bool QLibrary::unload ()调用了unload_sys;  
  3. void * QLibrary::resolve ( const char * 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  

原来如此啊。

我们仔细看下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 跨平台调用动态库实现的内容介绍完了,希望本篇文章对你有所帮助!

相关内容

热门资讯

如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
Windows恶意软件20年“... 在Windows的早期年代,病毒游走于系统之间,偶尔删除文件(但被删除的文件几乎都是可恢复的),并弹...
20个非常棒的扁平设计免费资源 Apple设备的平面图标PSD免费平板UI 平板UI套件24平图标Freen平板UI套件PSD径向平...
德国电信门户网站可实时显示全球... 德国电信周三推出一个门户网站,直观地实时提供其安装在全球各地的传感器网络检测到的网络攻击状况。该网站...
着眼MAC地址,解救无法享受D... 在安装了DHCP服务器的局域网环境中,每一台工作站在上网之前,都要先从DHCP服务器那里享受到地址动...
为啥国人偏爱 Mybatis,... 关于 SQL 和 ORM 的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行...