静态连接(dynamic|静态连接(dynamic link)和动态连接(static link)初步理解

前两天配置QT和VTK环境,焦头烂额啊,第一次配置个环境配置这么费劲的,这俩工具都不是微软出的开发库,需要自己编译,编译时间那个长。。。3,4个小时啊,等的花都谢了,好不容易编译好了,又出现了各种问题。
首先,早就听说过这两个库是跨平台的,当时觉得好牛逼啊,作为一个鄙视windows的linuxer,当然是要用跨平台的东西了,然后下载,安装,编译,经过了一晚上的折腾,QT编译好了,随便写了段TEST代码,编译,通过,运行,失败,问题是,失败就失败呗,居然提示未找到一个什么QT的动态链接库,网上搜了下,发现QT默认编译是dynamic的,当时那个悔,这不坑爹么,没办法,再编译一次,选成static,又是一夜,最后看一下,终于不提示了。
试着在虚拟机XP上运行一下,你不是跨平台厉害么,WINDOWS不同版本总能搞定吧?结果又提示错误,一看,是msvctrd.dll错误,我靠,立刻明白了,是MD和MT设置问题,赶明QT的STATIC参数设置只是内部库的静态连接,不包括QT和windows的连接啊!彻底被坑死,于是决定今晚再编译一晚上,应该没问题了。。。


好了,辈催的经历过后总要反思一些东西,那就说说静态连接和动态连接的理解吧。

说起静态连接和动态连接,就不得不说一下静态链接库和动态链接库。静态链接库在wiki里是这么定义的:statically-linked library is a set of routines, external functions and variables which are resolved in a caller atcompile-time and copied into a target application by a compiler, linker, or binder, producing an object file and a stand-alone executable。这段文字不难理解,意思就是静态链接库是一系列函数、变量,在编译、连接过程中,生成的一个目标文件。而动态链接库的概念则是:Dynamic-link library (also written without the hyphen), orDLL, is Microsoft's implementation of the shared library concept in the Microsoft Windows and OS/2 operating systems. 从这个概念基本看不出什么东西,只知道他是微软特有的库,并且是个分享库(shared library)。那么,动态连接和静态连接到底什么区别?其实就在于载入库的时间问题。在静态连接里,库会在compile-time被载入,而在静态连接里,库会在run-time载入。这个差异会造成一个有趣的现象,也就是程序的可移植性问题,打个比方,我写了段程序,用了动态连接,由于我机器上环境配置完整,因此不存在库缺失的问题,因此无论是编译还是运行,都没错,但是换台机器,突然用不了了,原因就是这台机器环境没配置好,程序动态寻找local library,结果失败,因此出错,而用静态连接则无此类问题,在编译阶段,编译器会把用到的所有函数、变量等,连接到一个文件里,程序移植后,由于不依赖本地函数库,因此可以正常运行。

有了以上知识,就不难理解Visual Studio里面的MT和MD的区别了,根据微软MSDN上的定义,MD的定义是:Causes your application to use the multithread- and DLL-specific version of the run-time library. Defines_MT and _DLL and causes the compiler to place the library name MSVCRT.lib into the .obj file. 这句话的重点在“DLL-spedific version of the run-time library”,也就是,用的是动态连接,而MT的定义是:Causes your application to use the multithread, static version of the run-time library. Defines _MT and causes the compiler to place the library name LIBCMT.lib into the .obj file so that the linker will use LIBCMT.lib to resolve external symbols. 重点在那个“static version of the run-time library”,也就是静态连接。

至此,问题完全解决。还有一点值得思考的是,微软自带的运行环境里看样子也是有静态库和动态库两套,那么在API开发领域,是不是每个库的开发都需要静态和动态两个版本呢?

【静态连接(dynamic|静态连接(dynamic link)和动态连接(static link)初步理解】

    推荐阅读