lib 和 dll

        最近单独做应用,从需求分析,框架设计,到编码实现,最后打包提供安装程序整个流程都走了一遍。对一些问题有了新的理解。项目中会引入第三方的库,一般会提供lib和dll,其实不是一般是必须。当然,开源库有源码,lib和dll 都可以自己编译生成,单独的静态库lib也是个特列。静态库不需要单独的索引信息,所有信息索引+逻辑都包含在lib文件中,所以文件会比较大,因为是编译阶段就链接入应用中的,也会导致应用程序比较大。

  • 为什么要同时提供lib和dll

        非常简单的一句话,“没有lib编译不过,没有dll程序跑不起来。”

        这句话引出编译类型的语言(不同于解释类型语言)开发应用的两个阶段,编译和运行。lib文件包含索引信息和地址信息,用来索引dll中真正的逻辑部分。dll导出这些信息,供外部调用。编译阶段,应用程序把索引和地址信息编译到应用程序内部。运行阶段,应用程序动态加载对应的dll(同名),完成逻辑调用,使用完动态卸载dll减少内存开销。

        所以应用程序打包的时候不需要再包含对应的lib文件。

  • 尽我所能,说一下程序从编译到运行的一般流程
  1.  整个项目的目录结构,Windows平台,当然首推VS系列集成开发环境,这个会自动构建项目的结构,*.sln是整个项目结构的描述信息,*.vcxproj 是单个项目的结构,包含当前工程所有头文件,源文件,以及需要依赖或引入的文件信息;类unix平台不太熟悉,大概知道整个项目是通过各自的makefile 文件组织的,角色类似*.vcxproj ,需要自己手动去构建,所以在这一点上,很多人认为不懂Linux 上程序开发的程序员不算真正的程序员,因为对整个项目,包括所有的边边角角,从生到死不能完全掌握。我也不说什么了,谁让现在Linux 服务器横行天下呢。不顾随着量子计算的发展,以后可能就没有服务器的概念了,通过“共享算力”只见应用不见服务。
  2.  编译阶段, 又分为预编译阶段和真正的编译阶段。预编译阶段主要是做一些头文件展开,宏计算等。简单点儿说就是新建一个文件,把所有头文件的依次添加进去,该计算的计算,该展开的展开(比如多层嵌套的宏定义),该内联的内联,供真正的编译阶段使用,所以这里就会有头文件重复包含,变量重复定义的问题了。真正的编译阶段,调用编译工具(一个可执行程序,这是一个开发工具的精髓所在,vc 的话好像叫cl.exe, 下次编译的时候可以打开控制台窗口看一下,工程如果很小,可能一闪而过了)把cpp源文件编译成*.obj文件,不同平台可能稍有差别,总之就是把源文件编译成对应的二进制文件,供链接阶段使用。这里还要多说一句,有一些中间件,比如MIDL,QMake等工具,扩展了一些属性,先通过自己的工具把自定义的属性转换成对应规范或者标准下语法,然后再进行预编译和编译的工作。新版的Qt 和VS 工具已经支持多核多线程编译,加快编译速度。毕竟对于很多大部头的库比如boost 单线程编译要好长时间。
  3. 链接的阶段就是把编译时候产生的二进制文件链接在一起,同时把引入的其他三方库链接进来,最后生成一个当前项目的文件。这个文件就有很多种了。比如生成lib和dll, 生成lib 和exe, 如果是静态库则只有一个lib文件。
  4. 运行阶段,程序运行的时候,根据需要动态加载或者卸载链接时候加入的lib对应的dll文件完成调用。

        至于如何编译生成自己的动态库以及如何使用,这里就不详细讲了。


猜你喜欢

转载自blog.csdn.net/moyebaobei1/article/details/81059512