Qt调用dll中的功能函数(转)

本文介绍如何使用Qt显示和隐式调用外部DLL文件。显示调用通过QLibrary类实现,涉及dll文件的加载、函数地址获取及释放;隐式调用需配合头文件和导入库文件使用,调用过程更为简便。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

声明: 事先我已经自己动手写了一个简单的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  }

还是隐式调用方便啊,直接就可以调用dll中的函数...

 

原帖位置:http://www.newwhy.com/2010/0829/9237.html

<think>我们参考上述引用,特别是引用[1][2][4]中展示的方法,使用QLibrary类来动态加载DLL调用中的函数。以下是详细步骤: 1. **包含必要的头文件**:在需要使用QLibrary的地方包含头文件`<QLibrary>`。 2. **声明函数指针类型**:根据DLL函数的原型,使用`typedef`定义函数指针类型。例如,如果函数原型是`int add(int, int)`,则定义: ```cpp typedef int (*AddFunc)(int, int); ``` 3. **加载DLL**:创建QLibrary对象,指定DLL的文件路径(如果DLL在系统路径或应用程序目录下,可以只写文件名)。 4. **解析函数**:使用`resolve()`方法获取DLL函数的地址,并赋值给函数指针。 5. **调用函数**:通过函数指针调用DLL中的函数。 6. **错误处理**:检查DLL是否加载成功以及函数是否解析成功。 下面是一个完整的示例代码(基于引用[1]修改): ```cpp #include <QApplication> #include <QLibrary> #include <QDebug> #include <QMessageBox> // 定义函数指针类型,用于调用DLL中的add函数(假设函数原型为int add(int, int)) typedef int (*AddFunc)(int, int); int main(int argc, char *argv[]) { QApplication app(argc, argv); // 加载DLL,假设DLL名为"MyMath.dll",放在应用程序目录下 QLibrary myLib("MyMath.dll"); // 尝试加载DLL if (myLib.load()) { QMessageBox::information(nullptr, "Success", "DLL loaded successfully!"); // 解析add函数 AddFunc add = (AddFunc) myLib.resolve("add"); if (add) { QMessageBox::information(nullptr, "Success", "Function resolved successfully!"); // 调用函数 int result = add(3, 4); qDebug() << "3 + 4 =" << result; } else { QMessageBox::critical(nullptr, "Error", "Failed to resolve function!"); } // 卸载DLL(可选,如果后续不再使用,可以卸载) myLib.unload(); } else { QMessageBox::critical(nullptr, "Error", "Failed to load DLL: " + myLib.errorString()); } return app.exec(); } ``` **注意事项**: - 确保DLL的架构(32位或64位)与你的Qt应用程序匹配。 - 如果DLL依赖其他DLL,请确保它们都在可访问的路径下。 - 在Windows上,DLL调用约定(如`__stdcall`或`__cdecl`)必须匹配。如果函数是`__stdcall`,则函数指针定义应包含调用约定,例如: ```cpp typedef int (__stdcall *AddFunc)(int, int); ``` - 在Linux下,动态库是.so文件,使用方法类似,只需将DLL文件名改为.so文件即可(引用[5]提到Linux下的情况,但未给出具体代码,可类比使用)。 **常见问题处理**(参考引用[3][4]): - 如果解析函数失败,检查函数名是否完全匹配(包括大小写)以及是否使用了导出修饰(如extern "C"避免C++名称修饰)。 - 如果加载失败,使用`QLibrary::errorString()`获取错误信息。 通过以上步骤,你可以在Qt应用程序中成功调用DLL中的函数。 §§相关问题§§ 1. Qt中如何调用使用`__stdcall`调用约定的DLL函数? 2. 如何解决Qt加载DLL时出现的“找不到指定模块”错误? 3. Qt中如何调用C++类导出的DLL(非extern "C"导出的类)?</think>### Qt调用DLL函数的方法 在Qt调用动态链接库(DLL中的函数,主要使用`QLibrary`类实现动态加载。以下是详细步骤和示例代码: #### 核心步骤 1. **定义函数指针类型** ```cpp typedef ReturnType (*FunctionName)(ParamType1, ParamType2); // 匹配DLL函数原型 ``` 2. **加载DLL文件** ```cpp QLibrary myLib("YourDLL.dll"); // 指定DLL路径 if (!myLib.load()) { // 处理加载失败 } ``` 3. **解析函数地址** ```cpp FunctionName myFunction = (FunctionName)myLib.resolve("ExportedFunctionName"); if (!myFunction) { // 处理解析失败 } ``` 4. **调用DLL函数** ```cpp ReturnType result = myFunction(param1, param2); // 执行函数 ``` #### 完整示例(Windows平台) ```cpp #include <QApplication> #include <QLibrary> #include <QDebug> #include <QMessageBox> // 定义函数指针类型(匹配DLL中的函数原型) typedef int (*AddFunction)(int, int); // 假设DLL中有int add(int a, int b) int main(int argc, char *argv[]) { QApplication app(argc, argv); QLibrary mathLib("MathOperations.dll"); // 加载DLL if (mathLib.load()) { AddFunction add = (AddFunction)mathLib.resolve("add"); // 解析函数 if (add) { int result = add(5, 3); // 调用DLL函数 qDebug() << "5 + 3 =" << result; } else { QMessageBox::warning(nullptr, "错误", "函数解析失败"); } mathLib.unload(); // 卸载DLL } else { QMessageBox::warning(nullptr, "错误", "DLL加载失败"); } return app.exec(); } ``` #### 关键注意事项 1. **调用约定匹配** - 如果DLL使用`__stdcall`,需修改函数指针定义: ```cpp typedef int (__stdcall *AddFunction)(int, int); ``` 2. **错误处理** - 使用`QLibrary::errorString()`获取详细错误信息: ```cpp if (!mathLib.load()) { qDebug() << "加载错误:" << mathLib.errorString(); } ``` 3. **跨平台注意** - Linux下使用`.so`文件: ```cpp QLibrary lib("libMyLib.so"); // [^5] ``` 4. **名称修饰问题** - C++ DLL建议使用`extern "C"`导出函数避免名称修饰: ```cpp extern "C" __declspec(dllexport) int add(int a, int b); ``` #### 常见问题解决 1. **函数解析失败** - 使用`dumpbin /exports YourDLL.dll`(Windows)检查导出函数名 - 确保函数签名(参数/返回值)完全匹配 2. **依赖缺失** - 使用[Dependency Walker](https://www.dependencywalker.com/)检查DLL依赖 3. **路径问题** - 将DLL放在可执行文件同级目录 - 或使用绝对路径:`QLibrary("C:/libs/MyDLL.dll")`
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值