动态链接库的小总结

时间:2021-09-07 15:49:37

        "动态链接库"这个名字非常的熟悉,却又常常让我非常的疑惑,比如今天。查了些资料也动了下手,把一些过程和结论记下来。

问题一、库文件的后缀

        一个比较常识的知识是,Linux下的静态库以.a结尾,而windows下的静态库以.lib结尾。Linux下的动态库以.so结尾,windows下的动态库以.dll。有一点值得注意的是,windows下VC使用的动态库一般还需要一个导入库,这个文件也是以.lib为后缀的。
        注意!我上一段最后一句话说的是VC下,但是windows下也有mingw这些编译系统。MinGW有Linux的血统,却要在windows下面干活,这就为一些误会埋下了伏笔。我也不饶弯子了,直接说答案了。在MinGW下(当然也是在windows下),动态库的后缀依然是dll,但是动态库的导入库却是以.a为后缀的。同时mingw使用和生成的静态库也是以.a为后缀的。
        总结一下,在windows中,VC和mingw的库文件后缀上的区别就是.lib和.a区别。相同点是,静态库和动态链接库导入库的后缀是一样的(容易混淆)。

问题二、库文件的内容

        在Linux下,静态库本质上就是把一些目标文件(.o)打包得到的库文件,相当于一堆目标文件。而动态链接库是把各个目标文件链接起来得到的,库文件中不仅有可执行代码还有导出符号表。一个工程在链接的时候,其实是不需要动态库中的可执行代码的,而是库文件中的地址符号表、函数信息等。可执行代码是在执行的时候才发挥作用的。为了得到库文件中的符号和函数等信息,链接的时候必修指定所使用的动态库。
        windows下的静态库和Linux的基本是一样,就是打包的目标文件。动态库的区别就比较大了,windows链接工程时并不需要.dll文件,而是需要动态链接库的导入库文件(可能是.lib也能是.a)。可以这样说吧!动态库相当于一本书,导入库就是书的目录。在链接工程的时候(不是执行的时候),我们需要的仅仅是目录信息。本质上动态库文件是包含导入库文件的信息的。不过windows从动态库中萃取出导入库信息,这样链接时就不需要动态库他老人家出马了!导入库小弟就能搞定问题了。
        我做了一个测试。在mingw下,使用动态库时不指定导入库,而是指定动态库,结果完全可以工作。我没有在VC下测试,估计是不行的。看来mingw虽然是“入乡随俗”了,但还是心在Linux,还是希望链接时直接使用动态库。

问题三、一个"&"的悲剧

        今天为了做上面的那个测试,我在Qt creator下建了一个简单的测试工程。其中我用GUI的向导添加了一个动态库,结果报各种undefined reference错误。然后搞了很久,就是弄不出来。网上各种查资料,别人都是这样做的呀!一度都怀疑这IDE了。后来,我用了绝对地址去指定动态库,结果报了一个"没有该目录"的错误,我一看就大概猜出问题了。我的工程路径大概是这样的:F:/PROGRAM/C&CPP/XXX。在解析文件目录的时候,qmake搞不定这个"&"了,然后就报错了。同样,用GUI向导的方法指定动态库的时候会在工程文件中添加这种代码"LIBS += -L$$PWD/../build-myDLL"。我估计,PWD肯定会返回正确的当前路径,但是qmake还是不认识这个路径,但是它又不敢怀疑操作系统大哥"说的话",所以就没有报错。然后我就给测试工程搬了个家,然后一切OK!这个小问题导致我花了很久的时间,不过还是解决了。