Windows平台下IDE编译基础知识

来源:互联网 发布:中国数据域名管理 编辑:程序博客网 时间:2024/06/05 18:28

程序需要编译然后需要运行,不管什么平台都是,但往往使用IDE的时候编译和运行都一起进行了,尤其是使用Windows平台提供的VS。一般来说,写程序不用到其它的开源库的时候,往往不用去管编译器或者集成环境到底做了什么,我们只用懂得如何运行,或者懂得如何简单的调试就好了,但这往往是写一些简单的或者逻辑本身不简单,但是形式简单的程序(因为有时候程序短小,不代表程序简单,可能算法思想是及其复杂的),我们要写一个稍微复杂点的应用程序,不可能完全不使用其它的库(全部利用Windows API完成),因为有些库就是Windows API的再集成封装,使得业务逻辑更清楚,调用更方便。

以Visual Studio集成编译环境为例,讲解一些基础的编译链接的事情。

从一个简单的程序说起:cout<<"Hello"<<endl;打印输出Hello,这个程序我没写全。按住Ctral+F5的时候就能打印出Hello,但这背后到底是怎么样的呢?

其实很简单:最终我们要在屏幕上打出Hello字符,肯定要使用硬件,那么就要用到硬件驱动程序,我们其实还用到了头文件<iostream>,而且我们还用到了cout这个对象,那么这些在哪呢?其实都是IDE帮我链接上了。利用C或C++写程序,我们会使用标准库函数(头文件里面的函数接口),而标准库函数肯定要使用系统调用(Windows API)才能最终能够打印出Hello;因为在Linux平台上,这个程序也是能运行的,所以,标准库函数提供的函数接口是一样的,但是不同系统平台上标准库函数的实现是使用了特定的系统调用(硬件驱动程序)。标准函数库的实现是已经生成的库文件,如果没有,我们还得自己编译标准函数库。

什么是库文件,在Windows平台下有两种库,lib和dll,lib由object模块组成,因为每个c或cpp文件编译成obj文件,很多个cpp就有很多个obj,太麻烦了,打个包将一类obj放在一起形成lib(说的比较粗)。那么如果我调用的函数的实现在iostream.obj中,那么我要把我的obj与这个iostream.obj链接在一起形成exe文件,但其实iostream.obj还得链接Windows API提供的库kernel.lib(系统提供的库可能就包含了驱动硬件程序),所以其实如果你懂得Windows API提供的函数接口,你可以不用标准函数库的函数而是直接使用Windows API提供的函数,打印Hello,这样就只需要链接你写的obj加上kernel.lib了,但为什么有C++或者Java等语言呢,因为这些函数库提供的逻辑更高级,更容易理解使用,如果我要打印Hello,我也可以直接通过驱动程序提供的库函数,绕过Windows系统,但越往底层,东西越晦涩,越难懂,最底层,你可能就直接写010101010,这些谁又能看懂进行后期维护呢?所以计算机就是一层一层的抽象封装打包,使得我们不用去管底层,可以使用接近我们逻辑的方式去写程序,加快了生产效率。

扯远了,拉回来,那我们写了个Hello程序,原来还需要链接这么多模块,因为我们使用了其它模块的函数实现。综合来看,我们写C或C++程序,首先使用到这些语言本身提供的标准函数库,然后标准函数库的实现又用到了系统调用。Hello.obj+C++的很多obj组成的Lib+系统调用的Lib。这看上去没问题,当然早期也是这种模式,但是存着时代的发展,发现每个程序最终都包含了一分C++标准库函数obj组成的Lib和系统调用的Lib,这样严重浪费内存!!!!!

所以前辈们想出来了动态运行时库(dll),即将这些都用到的库共享,即内存中有个地方专门存放了这些都要共享用到的库函数,所以C++库函数变成了dll,系统调用函数的实现也变成了dll。


虽然那些公共的库模块变成了dll形式,且以共享的形式在内存中只存在一份。最终程序的运行就变成了如下:源程序的obj+标准函数库的dll+系统调用的dll。其实这是理想状态,每个dll还会对应一个lib,即要想共享kerner.dll,在编译链接的时候还是要链接kerner.lib,那岂不是dll是多此一举,其实不然,因为此时的lib占内存已经很小(到底为什么要这样,不具体讲了,可以谷歌动态链接库和静态链接库的区别)。

那么现在就问题来了,这些标准函数库的lib和对应的dll以及系统调用的lib和对应的dll放在哪里了呢?????在Windows平台下,两个类型的dll是放在一起的,放在C:\Windows\System32目录下,而系统调用的lib存放在C:\Program Files\Microsoft SDKs\Windows\v7.1A\Lib目录下,标准函数库的lib则存放在IDE安装的目录下,不同版本的IDE可能实现的标准函数库的dll不一样,所以出现了很多msvcp110、msvcp71等等。。。

当然还有头文件的include目录没讲,include也分为两种:标准函数库的和系统调用的,目录路径和lib是一样的。

因为IDE集成环境已经默认了,编译链接我们写的程序的时候会自动去这些路径搜索相应的文件,所以当我们要使用自己编写的dll库的时候就需要指定让IDE去搜索我们自己dll所在的目录路径,这个需要在工程的属性中修改:


上图中的包含目录就可以指定去搜索我们的include文件路径,库目录就是lib路径,dll最好放在放在C:\Windows\System32目录下。当然我们可以把这些我们要用到的开源项目的include和lib和dll放在我们工程的目录下,就不用去特定修改工程属性,因为编译链接会现在工程目录下搜索。

除了以上步骤,还有一个关键步骤容易忽略,要添加lib依赖附加项:


通过以上步骤,你就可以使用自己编写dll库了,当然这个库可能还是会依靠dll编译时候的环境,即当dll是在VS2003环境编译的,可能在2010就不能使用了,不过只要你有源文件重新在2010下编译生成一下dll即可,具体的dll的编写就不详细讲了。

0 0