是关于如何加载dll或lib库的。可以看这篇bog   Qt调用dll中的功能函数点击打开链接

****************************************************************************************************************************************************

声明: 事先我已经自己动手写了一个简单的dll文件(myDLL.dll),C版接口的。并且用我前两篇有关DLL文章里面的方法,从dll中导出了导入库(.lib)文件,dll中有两个函数,原型如下:

   void HelloWorld();     //函数内部调用Win32 API,功能是弹出一个helloworld提示框   int add(int a,int b);  //实现两个数相加,并返回结果

下面分别通过显示调用和隐式调用两种方法,来模拟Qt如何调用外部dll文件中的功能函数,follow me....

预备知识:

1、如果在没有导入库文件(.lib),而只有头文件(.h)与动态链接库(.dll)时,我们才需要显示调用,如果这三个文件都全的话,我们就可以使用简单方便的隐式调用。

2、通常Windows下程序显示调用dll的步骤分为三步(三个函数):LoadLibrary()、GetProcAdress()、FreeLibrary()

其中,LoadLibrary() 函数用来载入指定的dll文件,加载到调用程序的内存中(DLL没有自己的内存!)

GetProcAddress() 函数检索指定的动态链接库(DLL)中的输出库函数地址,以备调用

FreeLibrary() 释放dll所占空间

1、显示调用

Qt提供了一个 QLibrary 类供显示调用。下面给出一个完整的例子:

  1. #include <QApplication>
  2. #include <QLibrary>
  3. #include <QDebug>
  4. #include <QMessageBox>
  5. #include "dll.h"             //引入头文件
  6. typedef int (*Fun)(int,int); //定义函数指针,以备调用
  7. int main(int argc,char **argv)
  8. {
  9. QApplication app(argc,argv);
  10. QLibrary mylib("myDLL.dll");   //声明所用到的dll文件
  11. int result;
  12. if (mylib.load())              //判断是否正确加载
  13. {
  14. QMessageBox::information(NULL,"OK","DLL load is OK!");
  15. Fun open=(Fun)mylib.resolve("add");    //援引 add() 函数
  16. if (open)                  //是否成功连接上 add() 函数
  17. {
  18. QMessageBox::information(NULL,"OK","Link to Function is OK!");
  19. result=open(5,6);      //这里函数指针调用dll中的 add() 函数
  20. qDebug()<<result;
  21. }
  22. else
  23. QMessageBox::information(NULL,"NO","Linke to Function is not OK!!!!");
  24. }
  25. else
  26. QMessageBox::information(NULL,"NO","DLL is not loaded!");
  27. return 0;  //加载失败则退出28}

myDLL.dll为自定义的dll文件,将其复制到程序的输出目录下就可以调用。显然,显示调用代码书写量巨大,实在不方便。

2、隐式调用

这个时候我们需要三个文件,头文件(.h)、导入库文件(.lib)、动态链接库(.dll),具体步骤如下:

1、首先我们把 .h 与 .lib/.a 文件复制到程序当前目录下,然后再把dll文件复制到程序的输出目录,

2、下面我们在pro文件中,添加 .lib 文件的位置: LIBS+= -L D:/hitempt/api/ -l myDLL

-L 参数指定 .lib/.a 文件的位置

-l  参数指定导入库文件名(不要加扩展名)

另外,导入库文件的路径中,反斜杠用的是向右倾斜的

3、在程序中include头文件(我试验用的dll是用C写的,因此要用 extern "C" { #include "dll.h" } )

下面是隐式调用的实例代码:

  1. #include <QApplication>
  2. #include <QDebug>
  3. extern "C"    //由于是C版的dll文件,在C++中引入其头文件要加extern "C" {},注意
  4. {
  5. #include "dll.h"
  6. }
  7. int main(int argv ,char **argv)
  8. {
  9. QApplication app(argv,argv);
  10. HelloWordl();          //调用Win32 API 弹出helloworld对话框
  11. qDebug()<<add(5,6);    // dll 中我自己写的一个加法函数
  12. return 0;  //完成使命后,直接退出,不让它进入事件循环
  13. }

************************************************************************************************************************************

本来是打算用隐身调用的,但是可能是库的原因,造成无法使用。库是别的公司提供的。so,用的第一种。在后面会贴一些我的code。

jida.h 部分 函数形成如下

  1. BOOL WINAPI JidaDllInstall(BOOL install);
  2. BOOL WINAPI JidaDllInitialize(void);
  3. BOOL WINAPI JidaDllUninitialize(void);
  4. DWORD WINAPI JidaBoardCountW(LPCWSTR pszClass, DWORD dwFlags);
  5. BOOL WINAPI JidaBoardOpenW(LPCWSTR pszClass, DWORD dwNum, DWORD dwFlags,/*@out@*/PHJIDA phJida);
  6. BOOL WINAPI JidaBoardClose(HJIDA hJida);
  7. DWORD WINAPI JidaI2CCount(HJIDA hJida);
  8. DWORD WINAPI JidaI2CType(HJIDA hJida, DWORD dwType);
  9. BOOL WINAPI JidaI2CRead(HJIDA hJida, DWORD dwType, BYTE bAddr, LPBYTE pBytes,DWORD dwLen);
  10. BOOL WINAPI JidaI2CWrite(HJIDA hJida, DWORD dwType, BYTE bAddr, LPBYTE pBytes,DWORD dwLen);

在要加载的cpp文件上写上QT,因为dll是window的,里面含有定义的宏DWORD这类,so加上windows.h

  1. #include <windows.h>
  2. #include <QLibrary>
  3. #include "jida.h"

定义指针函数以备调用如:一个add函数。下面第一行为函数,第二行为函数指针。

  1. //int add(int a,int b);
  2. //typedef int (*Fun)(int,int); //定义函数指针,以备调用

下面是我的main.cpp里面的。第一行pHandle是给dll的函数里面的api接口,不同dll接口不同,请忽略,不用在意。

主要是dll的加载。QLibrary jida_lib("jida.dll");

然后引用dll里面的函数。resolve是加载dll里面的函数。括号里面的(JidaDallInstall)是Dell里面的函数名。然后直接调用jida_install即可使用dll里面的JidaDallInstall函数。jida_install是自己自定义的。

  1. //加载dll 函数
  2. FunJidaInstal jida_install=(FunJidaInstal)jida_lib.resolve("JidaDllInstall");    //引用dll里面的JidaDllInstall() 函数

DWORD pHandle = 0; //句柄返回值

  1. //int add(int a,int b);
  2. //typedef int (*Fun)(int,int); //定义函数指针,以备调用
  3. //dll init uninit
  4. typedef BOOL WINAPI (*FunJidaInstal)(BOOL install);     //BOOL WINAPI JidaDllInstall(BOOL install);
  5. typedef BOOL WINAPI (*FunJidaDllInit)(BOOL install);    //BOOL WINAPI JidaDllInitialize(void);
  6. typedef BOOL WINAPI (*FunJidaDllUninit)(BOOL install);  //BOOL WINAPI JidaDllUninitialize(void);
  7. //板子
  8. typedef DWORD WINAPI (*FunJidaBoardCountW)(LPCWSTR,DWORD);             //DWORD WINAPI JidaBoardCountW(LPCWSTR pszClass, DWORD dwFlags); 板子数
  9. typedef BOOL WINAPI (*FunJidaBoardOpenW)(LPCWSTR,DWORD,DWORD,PHJIDA);//打开板子 BOOL WINAPI JidaBoardOpenW(LPCWSTR pszClass, DWORD dwNum, DWORD dwFlags,/*@out@*/PHJIDA phJida);
  10. typedef BOOL WINAPI (*FunJidaBoardClose)(HJIDA hJida);//BOOL WINAPI JidaBoardClose(HJIDA hJida); 板子关闭
  11. //I2C
  12. typedef DWORD WINAPI (*FunJidaI2CCount)(HJIDA);              //DWORD WINAPI JidaI2CCount(HJIDA hJida);
  13. typedef DWORD WINAPI (*FunJidaI2CType)(HJIDA, DWORD ); //DWORD WINAPI JidaI2CType(HJIDA hJida, DWORD dwType);
  14. typedef BOOL WINAPI (*FunJidaI2CRead)(HJIDA, DWORD , BYTE , LPBYTE ,DWORD );//BOOL WINAPI JidaI2CRead(HJIDA hJida, DWORD dwType, BYTE bAddr, LPBYTE pBytes,DWORD dwLen);
  15. typedef BOOL WINAPI (*FunJidaI2CWrite)(HJIDA, DWORD , BYTE , LPBYTE ,DWORD );//BOOL WINAPI JidaI2CWrite(HJIDA hJida, DWORD dwType, BYTE bAddr, LPBYTE pBytes,DWORD dwLen);
  16. //声明所用到的dll文件
  17. QLibrary jida_lib("jida.dll");
  18. //加载dll 函数
  19. FunJidaInstal jida_install=(FunJidaInstal)jida_lib.resolve("JidaDllInstall");    //引用dll里面的JidaDllInstall() 函数
  20. FunJidaDllInit jida_dll_init = (FunJidaDllInit)jida_lib.resolve("JidaDllInitialize");
  21. FunJidaDllUninit jida_dll_uninit = (FunJidaDllUninit)jida_lib.resolve("JidaDllUninitialize");
  22. FunJidaBoardCountW jida_board_countw = (FunJidaBoardCountW)jida_lib.resolve("JidaBoardCountW");
  23. FunJidaBoardOpenW jida_board_openw = (FunJidaBoardOpenW)jida_lib.resolve("JidaBoardOpenW");
  24. FunJidaBoardClose jida_board_close = (FunJidaBoardClose)jida_lib.resolve("JidaBoardClose");
  25. FunJidaI2CCount jida_i2c_count = (FunJidaI2CCount)jida_lib.resolve("JidaI2CCount");
  26. FunJidaI2CType jida_i2c_type = (FunJidaI2CType)jida_lib.resolve("JidaI2CType");
  27. FunJidaI2CRead jida_i2c_read = (FunJidaI2CRead)jida_lib.resolve("JidaI2CRead");
  28. FunJidaI2CWrite jida_i2c_write = (FunJidaI2CWrite)jida_lib.resolve("JidaI2CWrite");

进行下简单的判断,dll是否加载成功。.load是加载dll。jida_install是我调用dll里面的dll初始化程序。

等于是调用dll里面的函数,再次看是否加载ok。

    1. if (jida_lib.load()) //判断是否正确加载
    2. {
    3. cout << "qt lib load ok" << endl;
    4. }
    5. else
    6. {
    7. cout << "qt lib load error" << endl;
    8. }
    9. if(jida_install)
    10. {
    11. cout << "dell load ok" <<endl;
    12. }
    13. else
    14. {
    15. cout << "dell load error" <<endl;
    16. }

http://blog.csdn.net/linbounconstraint/article/details/47321103

加载dll、lib库(例子的代码很全)的更多相关文章

  1. Qt中加载Libevent静态库(通过reimp和rs两条语句将lib转为a)

    文章来源:http://blog.sina.com.cn/s/blog_731bf4c90102wnpr.html 本文仅是个人经验总结,若有错误欢迎指教! 最近要做一个跨平台的项目,同时也涉及到网络 ...

  2. 加载dll、lib库

    2.是关于如何加载dll或lib库的.可以看这篇bog   Qt调用dll中的功能函数点击打开链接 ************************************************** ...

  3. CS.动态加载DLL.动态生成.运行代码.BS.AutoFac管理实现类

    以英雄联盟为例.界面上经常有Load....xxxx.dll.一般都是加载子系统.比如装备系统.英雄系统等.在实际开发中很多项目非常庞大.都会分割成独立子解决方案开发.后期就需要加载回来.一般都是利用 ...

  4. C#调用mingw的so库时无法加载DLL###.so 找不到指定的模块

    使用C#调用mingw的so,报了c# 无法加载DLL“###.so”,: 找不到指定的程序. (异常来自 HRESULT:0x8007007E)开始以为是dll路径问题,使用全路径确认正确后仍然无法 ...

  5. Delphi静态加载DLL和动态加载DLL示例

    下面以Delphi调用触摸屏动态库xtkutility.dll为例子,说明如何静态加载DLL和动态加载DLL. 直接上代码. 1.静态加载示例 unit Unit1; interface uses W ...

  6. 内存加载DLL

    1.前言 目前很多敏感和重要的DLL(Dynamic-link library) 都没有提供静态版本供编译器进行静态连接(.lib文件),即使提供了静态版本也因为兼容性问题导致无法使用,而只提供DLL ...

  7. delphi 动态加载dll

    引入文件 DLL比较复杂时,可以为它的声明专门创建一个引入单元,这会使该DLL变得更加容易维护和查看.引入单元的格式如下: unit MyDllImport; {Import unit for MyD ...

  8. 动态加载dll的实现+远线程注入

    1.在目标进程中申请内存 2.向目标进程内存中写入shellcode(没有特征,编码比较麻烦) 3.创建远线程执行shellcode 之前可以看到shellcode很难编写还要去依赖库,去字符串区等等 ...

  9. 尝试加载 Oracle 客户端库时引发 BadImageFormatException。问题记录

    电脑是win8 64位,安装oracle 11g r2 64位的,谁知道一切装完毕后,打开项目却连不上oracle数据了...首先是pl/sql连不上,装了oracle服务器,应该是不用再装客户端,p ...

随机推荐

  1. [Javascript] Javascript 'in' opreator

    If you want to check whether a key is inside an Object or Array, you can use 'in': Object: const obj ...

  2. 【u028】数列的整除性

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 对于任意一个整数数列,我们可以在每两个整数中间任意放一个符号'+'或'-',这样就可以构成一个表达式, ...

  3. [TypeScript] Typescript Interfaces vs Aliases Union & Intersection Types

    TypeScript has 'interface' and 'type', so when to use which? interface hasName { firstName: string; ...

  4. [React] Render Basic SVG Components in React

    React loves svg just as much as it loves html. In this lesson we cover how simple it is to make SVG ...

  5. 实际工程Quartz与Spring设计与实现一体化的热部署

    1.需求说明 主要负责项目任务调度.使用Quartz.以Spring为辅助. 如今有这样一个需求:我们不知道管理员想设定过多厂时间运行主任务,须要在配置文件定义.在配置好后须要马上运行.实现热部署. ...

  6. VS Code插件之Cordova Tools

    原文:VS Code插件之Cordova Tools 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u011127019/article/detai ...

  7. C# 使用Emit深克隆

    原文:C# 使用Emit深克隆 有人问,复制一个类所有属性到另一个类有多少方法?这也就是问深克隆有多少个方法,容易想的有三个.直接复制,反射复制,序列化复制.但是性能比较快的有表达式树复制 IL复制两 ...

  8. 使用HAXM为QEMU for Windows加速

    QEMU是一款支持多种CPU的虚拟化软件,本身基于软件虚拟化,效率不高,在linux下可以基于KVM加速,据说可以获得接近物理机的性能.网上有很多关于QEMU+KVM的使用说明,但是KVM仅用于lin ...

  9. Objective-C的基础数据结构

    类的数据结构 Class(指针) ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 typedef struct objc_c ...

  10. 从DOS bat启动停止SQL Server (MSSQLSERVER)服务

     由于机器上装了SQL Server2008,导致机器开机变慢,没办法只能让SQL Server (MSSQLSERVER) 服务默认不启动.但是每次要使用SQL Server时就必须从控制面板-管理 ...