DLLLIB的区别 :
1.DLL是一个完整程序,其已经经过链接,即不存在同名引用,且有导出表,与导入表lib是一个代码集(也叫函数集)他没有链接,所以lib有冗余,当两个lib相链接时地址会重新建立,当然还有其它相关的不同,用lib.exe就知道了;
2.在生成dll时,经常会生成一个.lib(导入与导出),这个lib实际上不是真正的函数集,其每一个导出导入函数都是跳转指令,直接跳转到DLL中的位置,这个目的是外面的程序调用dll时自动跳转;
3.实际上最常用的lib是由lib.exe把*.obj生成的lib。(引用这里 )
Qt 想调用DLL怎么办呢?最先想到的是直接调用试试看:包含头文件,并把DLL文件拷到当前目录下,调用声明的函数,结果链接时和预想的一样出错了。修改 Makefile.debug,的链接选项也不行。Windows里的gcc调编译时用的库是和Linux一样的.a文件。其实,上面用VC直接调用 DLL的方法,在Windows里其实叫“隐式链接”,相对的叫“显式链接”,可以参考CSDN的解释 。

Qt调用DLL方法一:使用Win32 API 
在显式链接下,应用程序必须进行函数调用以在运行时显式加载 DLL。为显式链接到 DLL,应用程序必须:
? 调用 LoadLibrary(或相似的函数)以加载 DLL 和获取模块句柄。
? 调用 GetProcAddress,以获取指向应用程序要调用的每个导出函数的函数指针。由于应用程序是通过指针调用 DLL 的函数,编译器不生成外部引用,故无需与导入库链接。
? 使用完 DLL 后调用 FreeLibrary。
例如:
typedef UINT (CALLBACK* LPFNDLLFUNC1)(DWORD,UINT);

HINSTANCE hDLL; // Handle to DLL
LPFNDLLFUNC1 lpfnDllFunc1; // Function pointer
DWORD dwParam1;
UINT uParam2, uReturnVal;

hDLL = LoadLibrary(”MyDLL”);
if (hDLL != NULL)
{
lpfnDllFunc1 = (LPFNDLLFUNC1)GetProcAddress(hDLL,
“DLLFunc1″);
if (!lpfnDllFunc1)
{
// handle the error
FreeLibrary(hDLL);
return SOME_ERROR_CODE;
}
else
{
// call the function
uReturnVal = lpfnDllFunc1(dwParam1, uParam2);
}
}

需要说明的是,typedef UINT (CALLBACK* LPFNDLLFUNC1)(DWORD,UINT);是声明想要调用的函数指针,这个函数的参数必须和DLL里面的一样。DLLFunc1是DLL里面 的“实际的函数名”,必须和头文件里面声明的一样,否则将会调用失败。使用需要加Windows.h 头文件。Windows里的Qt是用Mingw GCC来编译,而Mingw GCC可以支持Win32的API。使用时并不需要包含头文件。这个方法没有实际验证,理论上是可以的。

Qt调用DLL方法二:使用QtAPI 
对于调用DLL的方法,Qt原来本身就有相应的类来实现,用起来和Win32的步骤差不多。下面是代码,已经编译通过。在控制台依次输入qmake –project、qmake、 nmake,即可。
#include
#include
#include

//动态链接不需要包含LTM8000D.h头文件

typedef int ( *pcom_open)(int , int , int ); //定义函数指针

int main(int argc, char *argv[])
{

int ret; //函数返回值
int port=1; //端口
int baud=0; //波特率
int rtsdtr=0; //串行口485方向控制设置:

QApplication a(argc, argv);
QLabel label1(”label-1″); //显示打印信息,将就着用了。。。
QLabel label2(”label-2″);
QLibrary mylib(”LTM8000D.DLL”);
if(mylib.load())
{
label1.setText(”load DLL success!…”);
pcom_open open=(pcom_open)mylib.resolve(”ltm_com_open”); //“ltm_com_open”为DLL包含的实际函数名,必须实际存在

if(open)
{

ret=open(port, baud, rtsdtr); //在这里调用DLL里的函数
label2.setText(”resolve ok…”);
}
else
{
label1.setText(”resolve failed…”);
}

}

else
{
label2.setText(”load DLL failed…”);
}
label1.show();
label2.show();
return a.exec();
}

Qt调用DLL方法三:直接调用 DLL
VC的引用库文件为xxx.lib, GCC的为xxx.a,通过比较两种库文件的格式,发现很相似。于是把xxx.dll,xxx.lib和xxx.h复制到Qt的project下,直接把xxx.lib改为xxx.a, 根据Qt的库名字的格式, 在xxx.a的前面加上lib, 即为libxxx.a。

再在Qt的.pro文件中最后面加上

LIBS += -L. –lxxx //增加当前目录下的libxxx.a

在Qt的源文件中加上

#include “xxx.h”

现在就可以直接调用xxx.h中的函数了。

// xxx.h

#ifndef XXX_H

#define XXX_H

WINAPI int xxx_func(void);

#endif

// main.cpp

#include “xxxh”

#include

#include

int main(int argc, char *argv[])
{

QApplication a(argc, argv);
QLabel label1(”label-1″); //显示打印信息,将就着用了。。。
if(xxx_func()) //“xxx_func”为DLL包含的实际函数名,必须实际存在
{
label1.setText(”Run DLL success!…”);

}
label1.show();
return a.exec();
}

http://blog.sina.com.cn/s/blog_a401a1ea0101bwgf.html

Windows下gcc以及Qt的DLL文件调用之总结(三种方法)的更多相关文章

  1. 痞子衡嵌入式:在IAR开发环境下将关键函数重定向到RAM中执行的三种方法

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是在IAR开发环境下将关键函数重定向到RAM中执行的三种方法. 嵌入式项目里应用程序代码正常是放在 Flash 中执行的,但有时候也需要将 ...

  2. PHP获取文件后缀名的三种方法

    如下: <? PHP获取文件后缀名的几种方法1: function get_file_type($filename){ $type = substr($filename, strrpos($fi ...

  3. Python判断文件是否存在的三种方法

    通常在读写文件之前,需要判断文件或目录是否存在,不然某些处理方法可能会使程序出错.所以最好在做任何操作之前,先判断文件是否存在. 这里将介绍三种判断文件或文件夹是否存在的方法,分别使用os模块.Try ...

  4. Python判断文件是否存在的三种方法【转】

    转:http://www.cnblogs.com/jhao/p/7243043.html 通常在读写文件之前,需要判断文件或目录是否存在,不然某些处理方法可能会使程序出错.所以最好在做任何操作之前,先 ...

  5. Python 判断文件是否存在的三种方法

    通常在读写文件之前,需要判断文件或目录是否存在,不然某些处理方法可能会使程序出错.所以最好在做任何操作之前,先判断文件是否存在. 这里将介绍三种判断文件或文件夹是否存在的方法,分别使用os模块.Try ...

  6. springMVC文件上传的三种方法

    这时:commonsmultipartresolver 的源码,可以研究一下 http://www.verysource.com/code/2337329_1/commonsmultipartreso ...

  7. 用matlab脚本语言写M文件函数时用三种方法简单实现实现DFT(离散傅里叶变换)

    %用二重循环实现DFT: function xk=dt_0(xn); %define a function N=length(xn); %caculate the length of the vari ...

  8. 痞子衡嵌入式:MCUXpresso IDE下将关键函数重定向到RAM中执行的几种方法

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是MCUXpresso IDE下将关键函数重定向到RAM中执行的几种方法. 前段时间痞子衡写了一篇 <在IAR开发环境下将关键函数重 ...

  9. 关于在windows下部署发布QT程序的总结

    原文请看:http://www.cnblogs.com/javaexam2/archive/2011/05/18/2632916.html 关于在windows下部署发布QT程序的总结 2008-06 ...

随机推荐

  1. php后台如何避免用户直接进入方法实例

    这篇文章介绍了php后台如何避免用户直接进入方法实例,有需要的朋友可以参考一下 1)创建BaseController控制器继承Controller(后台的一切操作要继承BaseController): ...

  2. vs2010中的反编译

    有这样的需求,一个.dll文件,如何查看里面的代码呢?网上有很多关于反编译的运用的. http://blog.csdn.net/lyflcear/article/details/8102057 昨天( ...

  3. Linq中延迟查询和立即查询

    //立即查询 public static void NowExecute() { var results = new int[]{5,4,3,2,1,6,7,8,9,0 }; int i = 0; v ...

  4. html css布局

    这几天有点急于求成了,原来每一门技术都像大海,只有深入其中才发现它比看到的更要深广的多. 虽然忙里偷闲的看了HTML5,NODE.JS,JAVASCRIPT核心等许多东西,但是真正掌握的不足十分之一, ...

  5. WPF 心形线算法

    今天在网上查找下心形算法公式,自己便按照公式写下来标记在博客,主要是方便以后查看! private int maxStep = 520; private double radius; private ...

  6. COUNT(*),count(1),COUNT(ALL expression),COUNT(DISTINCT expression)

    创建一个测试表 IF OBJECT_ID( 'dbo.T1' , 'U' )IS NOT NULL BEGIN DROP TABLE dbo.T1; END; GO )); GO INSERT INT ...

  7. swift UIAlertController教程

    在iOS8中,UIAlertView与UIActionSheet都已经退休,取而代之的是UIAlertController!它的使用示范如下://弹出一个警告框,标题是“提示”,信息是“我的博客:oa ...

  8. 关闭ios虚拟键盘的几种方法

    在iOS应用开发中,有三类视图对象会打开虚拟键盘,进行输入操作,但如何关闭虚拟键盘,却没有提供自动化的方法.这个需要我们自己去实现.这三类视图对象分别是UITextField,UITextView和U ...

  9. iOS 进阶 第四天(0329)

    0329 UIScrollView的常见属性及其解释 常见属性,如下图: 具体解释,如下图: 喜马拉雅设置的例子 代码: 效果     

  10. SpringMVC Cache注解+Redis

    依赖jar包:Xml代码  收藏代码 <!-- redis -->              <dependency>                  <groupId ...