当前位置:   article > 正文

QT(51)-动态链接库-windows_qt调用32位的第三方动态库

qt调用32位的第三方动态库

1.qt- 调用win32 DLL
2.qt- 调用MFC DLL

 


0概述:

01.扩展DLL:
      必须有一个DllMain()函数,且调用AfxInitExtensionModule()函数。
      CRuntimeClass类-初始化函数CDynLinkLibrary。

02.windows定位DLL文件:
   1)exe同一目录
   2)进程当前目录GetCurrentDirectory()
   3) windows系统目录 GetSystemDirectory()  c:\windows\system32
   4) windows目录  GetWindowsDirectory() c:\windows
   5) 列在path环境变量中的一系列目录。

03.32位和64位不能混用
   
 EXE 和DLL需要位数相同。
04. def 文件:
   
 
041:VC6.0创建dll文件时自动生成.def文件,但里面没有函数名,只表名这是一个DLL文件。

  1. ; myvcdll.def : Declares the module parameters for the DLL.
  2. LIBRARY "myvcdll"
  3. DESCRIPTION 'myvcdll Windows Dynamic Link Library'
  4. EXPORTS
  5. ; Explicit exports can go here

   042:VS2019下创建DLL时不会生成.def文件。
05.dll和exe在同一个文件夹下:
      单独运行EXE时如果出现如下错误:

修改环境变量:把编译使用的路径放到最上面,且重启机器。
这是原来的:

06 dll和exe的文件编码要一致。
 
1.qt- 调用win32 DLL
   1.1 DLL文件编写 :关键字+.def模块文件

       1.11 导出方式:关键字 _declspec(dllexport)mydll.h
        C++:支持重载机制,处理函数名,加入函数的返回类型。
        C: 没有extern “C”时会提示,函数找不到的错误码(DWORD dw=::GetLastError();,得到dw=127)
        1.111 mydll.h头文件如下创建,可被QT和VS创建的exe调用:

  1. #ifndef _MYDLL_H //防止重复引用
  2. #define _MYDLL_H
  3. # ifdef __cplusplus //如果这是一段cpp代码,那么加入 extern"C"{} 处理其中的代码。
  4. extern "c"{
  5. #endif
  6. _declspec(dllexport) void f();
  7. _declspec(dllexport) int min(int a, int b);
  8. #ifdef __cplusplus
  9. }
  10. #endif
  11. #endif

     1.112 mydll.h头文件如下创建 ,只能被VS创建的exe调用:

  1. #define MYDECLARE_PUBLIC extern "C" _declspec(dllexport)
  2. _declspec(dllexport) void myDLL(void);

  1.12 mydll.cpp

  1. #include "mydll.h"
  2. void f()
  3. {
  4. MessageBox(0,_T("你好,世界"),0,0);
  5. }


   1.12 模块定义文件:(.def+.h+.cpp)
     
 1.121.testdll.def文件:文件中的函数名就是要导出的函数名            

  1. LIBRARY MYDLL; //可有可无,DLL名称
  2. DESCRIPTION "这是我的DLL"; //可有可无,DLL的解释
  3. EXPORTS //必须有 后面是函数名或者变量名
  4. f1
  5. f2

@ordinal 允许用序号导出函数,而不是以函数名导出。
             
       
1.122.tesdll.h 文件

  1. #ifndef _TEST_H
  2. #define _TEST_H //防止重复引用
  3. #include "tchar.h" //为了使用_T
  4. int f1(TCHAR *sz,int n);
  5. void f2();
  6. #endif

       1.123.testdll.cpp文件

  1. #include "Test.h"
  2. #include "windows.h" //为了使用MessageBox
  3. int f1(TCHAR *sz, int n)
  4. {
  5. MessageBox(0,sz, 0, 0);
  6. return n;
  7. }
  8. void f2()
  9. {
  10. MessageBox(0, _T(" 你好,f2"), 0, 0);
  11. }

1.2DLL调用
   1.21隐式链接
          导入.lib文件。
          包含头文件。
          exe中调用dll中的函数和类。    

配置:
1.211导入.lib 文件:
链接器->常规->附加库目录:lib库目录
链接器->输入->附加依赖项:lib文件名


 

 1.212包含头文件:
    C/C++->常规->附加包含目录



1.213 exe中调用dll中的函数

  1. #include "../test//mydll.h"
  2. #pragma comment(lib, "mydll.lib") //隐式链接方式
  3. void myexe::OnBnClickedpbt()
  4. {
  5. f(); //调用dll中的f() 函数
  6. }

2.qt- 调用MFC DLL
  2.11win32 API
  2.12qt自身的API
  2.13直接调用DLL
  2.14可视化设置
   
 
2.11.加载DLL::LoadLibrary(L"D:\C++\myDll\mydll.dll");
    2.12. 得到导出函数的地址:lpfnDllFunc1 = (FUNC)GetProcAddress(hDLL,"f");

    2.13.释放句柄:FreeLibrary(hDLL);

  1. #include <windows.h>
  2. #include <QMessageBox>
  3. typedef void (* FUNC) ();
  4. void Dialog::on_pushButton_clicked()
  5. {
  6. DWORD dw;
  7. HINSTANCE hDLL; // Handle to DLL
  8. FUNC lpfnDllFunc1; // Function pointer
  9. QString str;
  10. //1.加载
  11. hDLL = ::LoadLibrary(L"D:\C++\myDll\mydll.dll");
  12. if (hDLL)
  13. {
  14. //2.得到函数句柄
  15. lpfnDllFunc1 = (FUNC)GetProcAddress(hDLL,"f");
  16. if (!lpfnDllFunc1)
  17. {
  18. dw = ::GetLastError();
  19. FreeLibrary(hDLL);
  20. str.sprintf("GetProcAddress failed:%d",dw);
  21. QMessageBox::information(this,"Error code",str);
  22. }
  23. else
  24. {
  25. //3. 调用函数+释放句柄
  26. lpfnDllFunc1();
  27. FreeLibrary(hDLL);
  28. }
  29. }
  30. else
  31. {
  32. dw = ::GetLastError();
  33. str.sprintf("Load dll failed:%d",dw);
  34. QMessageBox::information(this,"Error",str);
  35. }
  36. }

  2.12 calldefdll
      2.121创建项目
      2.122 dll ,lib, def 文件放在同一路径下。

      .def 指定导出函数的具体名字。

  1. EXPORTS
  2. f1
  3. f2

  mydll.h  

  1. #ifndef _TEST_H
  2. #define _TEST_H //防止重复引用
  3. #include "tchar.h" //为了使用_T
  4. int f1(TCHAR *sz,int n);
  5. void f2();
  6. #endif

  mydll.cpp

  1. int f1(char *sz,int n)
  2. {
  3. MessageBoxA(0,sz,0,0);
  4. return n;
  5. }


  2.12QT自身的API
   
2.21加载动态库文件  QLibrary myLib("mydll") //动态链接库文件的基本名:mylib 非文件名。
                                      是否成功:isLoaded()
                                      得到函数地址:resolve()
                                      卸载:unload()
    被加载动态库
   

  1. void Dialog::on_pushButton_clicked()
  2. {
  3. Qlibrary lib("myDll");
  4. }

  2.13直接调用DLL
   
2.131 .lib.dll文件放入exe同一路径下。
    2.132  exe文件编写:
        2.1321exe工程配置文件   .pro文件    导入.lib文件

  1. LIBS += -L$$PWD/ ./ -lmydll
  2. // -L 导入库路径 相对路径 $$PWD 当前路径 -l库的基本名(没有后缀的文件名)
  3. LIBS += -LD:\QTPrj\build-code_qbytearray-Desktop_Qt_5_14_2_MinGW_32_bit-Debug\debug -lmydll
  4. // -L 导入库路径 绝对路径

     2.1322exe新建.h文件,mydll.h 与DLL中的不是一个!!
            ADD new...

  1. #ifndef MYDLL_H
  2. #define MYDLL_H
  3. extern "C" void f();
  4. #endif // MYDLL_H

   2.1323 exe中.cpp文件编写      

  1. #include "myDll.h"
  2. void MainWindow::on_pushButton_clicked()
  3. {
  4. myDLL();
  5. }


  2.14可视化设置 

 

 

 

 


 

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号