随笔- 286  评论- 28  文章- 32 

Qt动态库静态库的创建、使用、多级库依赖、动态库改成静态库等详细说明

本文描述的是windows系统下,通过qtcreator在pro文件中添加动态库与静态库的方法:

1、添加动态库(直接添加动态库文件.dll,非子项目)

通过qtcreator创建动态库的方法就不在此处赘述了。

唯一值得强调的是动态库与静态库的创建在pro文件中配置的区别在于静态库多了

CONFIG += staticlib ,如下图所示(稍安勿躁,以下示例的工程代码最后会统一打包上传)

注:mingw32编译器生成的动态库文件包括一个***.dll和一个***.a文件(这里的.a文件为导入库,类似于vc动态库生成的lib文件, .dll.a类型文件是MinGW下的DLL文件的imp-lib,即与MSVS下DLL文件附带了一个引入库.lib类似。在MSVS下编程,当要使用DLL文件时,在开发时必须要有.lib文件才能链接通过。在MinGW无需imp-lib库文件的帮助,可直接与.dll文件链。在大多数情况下,.dll.a文件不起作用。具体见https://www.cnblogs.com/liushui-sky/articles/9488020.html),vc编译器生成的动态库文件包含一个***.dll和一个***.lib文件

 

接下来言归正传,如何添加动态库,右击工程名,选择“添加库”,由于是添加外部的库,就选择“外部库”,如果是子项目的生成的动态库,则选择“内部库”,系统库就不在此介绍了。

这里需要吐槽下,貌似qtcreator添加外部库的步骤在windows下只能添加.lib文件,也就是说主要用于添加vc编译器生成的动态库文件,这个比较坑,linux下到是没有这个问题。

那么qtcreator mingw32编译器生成的库如何添加呢,在看上面两幅图的第一幅,添加库的最终目的是“请将库和它的include路径添加到.pro文件中”,所以我们直接把库文件和include路径直接写到pro文件中即可。添加方法主要有以下几种,不赘述,直接看图

这样动态库就添加好了。

2、添加静态库(直接添加静态库文件.a,非子项目)

与添加动态库类似,不详细说明,直接看图,相信聪明的你一看就明白

pro文件:                              编译生成文件(静态库***.a文件):

                

接下来,如何添加静态库,右击工程名,选择“添加库”,由于是添加外部的库,就选择“外部库”,如果是子项目的生成的动态库,则选择“内部库”,系统库就不在此介绍了。

还是得说声抱歉,貌似qtcreator添加外部库的步骤在windows下不管是动态库和静态库都只能添加.lib文件,也就是说主要用于添加vc编译器生成的动态库(库文件.dll和其引导文件.lib)和静态库文件(.lib文件),这个比较坑,linux下到是没有这个问题。

那么上面qtcreator mingw32编译器生成的静态库如何添加呢,其实跟添加动态库是一样的,指定库文件和include路径,具体看第一节的图。

3、添加动态库或静态库子项目

当一个工程包含多个子项目时,往往一个带main主文件的项目作为主项目(即最后运行的程序),其它子项目以生成库(动态库或者静态库)的方式让主项目进行包含。

未来调试方便,我们通过添加”内部库”的方式建立依赖关系,达到动态关联的目的。添加方法如下:

最终在test_lib.pro的文件中添加了以上代码,但是由于mingw32生成的静态库不带lib文件,所以以上最后3行要删除,即下图中的注释部分不需要

添加内部动态库更加简单,都不用删除,见下图:

 

 4、多级库依赖

以下图中项目为例介绍,test_lib依赖test_lib.2,而test依赖test_lib,所以也要依赖test_lib2,记住不管动态库还是静态库子项目都要把多级依赖的库都添加上,而且还要注意顺利(具体如图中红线所示),否则哪怕编译未出错,也无法正常实现功能。也许有人先在test项目pro中加上了test_lib2的依赖,然后编译通过了,然后再注释掉重新编译还是可以正常运行,但是我想告诉你的是----这都是假象,不相信你把编译的文件都删掉再编译就不行了,这只不过是qtcreator重新构建的功能没有把一些编译文件清除干净而已,所以还是要求把依赖项都加上。这个依赖关系的学习可以具体看这篇文章https://www.cnblogs.com/liushui-sky/articles/9487600.html

 注意:这里包含的顺序与库依赖的顺序刚好相反,最底层的子项目在上面,最顶层的项目在下面

 

 

 

 

5、动态库、静态库混合使用

这个是否可以混合使用呢,答案当然是可以的了,为什么这么说呢,一个很简单的道理——动态编译的qt库本身都是dll的,而静态编译的子项目生成的库为静态库,既然这样可以 

使用说明就可以一起混合使用。具体还是以上述项目为例:

 

 

这里把test_lib2配置为生成静态库,test_lib不变,仍为动态库,test依次包含,运行结果OK,说明可行。

 项目示例代码位置:https://files.cnblogs.com/files/liushui-sky/TEST123.rar

6.动态库改成静态库

 通过qtcreator创建的动态库项目中除pro文件中有专门的“DEFINES +=******* ”定义之外,还会有 ******_global.h的头文件生成。如以上TEST12项目中增加子项目(动态库)test_share_lib。

如果项目后期需要改成静态库的话,除了pro中增加“CONFIG += staticlib”之外,还需要把这个头文件和DEFINES删除掉,并且在test_share_lib.h的头文件中把下图中的红色划线部分删除,否则当他还依赖其它几个静态库时会报找不到库(注:_imp__***相关的问题一般是动态库相关的问题)的报错及dllimport相关的报警,具体见下图,这个错误很隐蔽,切记,如果没有删除这些,有时候编译也能过,那是应该有些编译文件(还是动态库时候编译的文件)没有删除干净的原因,这个前面已经说明过类似的情况了,切记

未注释而报错的项目代码位置:https://files.cnblogs.com/files/liushui-sky/TEST123_2.rar

你只需要按上删除pro中的内容和test_share_lib_global.h头文件,并按上修改test_share_lib.h,就不会报错,可以自己试一下吧。

 

posted on 2018-08-16 15:40  苦涩的茶  阅读(...)  评论(...编辑  收藏