关于c/c++中 编译链接的问题。
最近学mfc,搞了半天winmain在哪里....最后终于知道在appmodul.cpp里面我去......但是又发现工程文件里面没有appmodul.cpp。然后发现工...
最近学mfc,搞了半天winmain在哪里.... 最后终于知道在appmodul.cpp里面 我去......
但是又发现工程文件里面没有 appmodul.cpp。 然后发现工程中只包含了一些头文件
注意到以前的include<stdio.h>,头文件里不一般只有声明么? include了声明之后,编译器就能自动找到这些声名的实现代码? 这个编译链接的过程到底是怎样的,不需要了解太深,求大神大概说一说......... 展开
但是又发现工程文件里面没有 appmodul.cpp。 然后发现工程中只包含了一些头文件
注意到以前的include<stdio.h>,头文件里不一般只有声明么? include了声明之后,编译器就能自动找到这些声名的实现代码? 这个编译链接的过程到底是怎样的,不需要了解太深,求大神大概说一说......... 展开
5个回答
2014-03-14
展开全部
这个问题不是一两句话可以解释完
1、微软提供给我们的MFC已经编译成静态LIB和动态LIB,同时,为方便调试,微软将MFC源码(CPP文件)也放到VC里一起发布了;这里会存在两种情陆尺况,如果是静态LIB,那么功能代码会在链接时链接进你的EXE文件中,所以这种静态LIB方式时,EXE文件通常都比较大;如果是动态LIB的方式,那么运行的时候就需要mfcxxx.dll文件,但EXE文件体积比较小
2、如果你理解了1,我再进一步解释,MFC工程配置的时候默认会链接mfcxxx.lib的,所以你的工程里只需要包含对应的头文件,例如 afxxxx.h之类的文件即可,编译器在编译阶段是不需要知道具体实现代码在哪里的,它只需要知道声明即可编译通过,同时编译器会将那些外部的函数(即不是在当前CPP文件实现的函数)标记为需要修复的(我们先把它叫做修复吧);那么,假如我用了一个MFC的函数,现在我只有声明,它是怎么找到具体的实现代码呢,这就是链接器的工作了,刚才我说过,MFC工码悉判程默认是会链接mfcxxx.lib的,所以链接器在工作的时候,它会遍历所有编译过的文件,从里面找出要修复的项,然后再遍历LIB文件,如果在LIB文件里找到对应的实现,那么链接器会把编译阶段留下的手尾FIX掉
3、如果你理解了2,我们再进一步解释2;链接器链接LIB的时候,会有两种情况,第一种,这个LIB本身是一个静态LIB,包含了具体的实现;第二种,这个LIB本身只是一个中介,它是指向DLL的某个函数的;对于第一种情况,链接器会把用到的所有代码链接进去,注意,在Release版本情况下,链接器只会把用的的函数链进去,就是说,即使你的静态LIB有10MB,你也不需要担心编译出来的EXE有10MB,它只会把用到的函数链进去;;对于第二种,是指向DLL某个函数的,链接器会迟改在EXE的PE部里的导入表部分,增加一个项,这个项指向DLL的函数,同时在修复编译阶段留下手尾的地方,让它JMP(跳转)或CALL(调用)到我们DLL函数里
以上纯属个人解释,因为在编译链接阶段是非常复杂的,一时间没办法完全解决齐,有问题可以继续追问
1、微软提供给我们的MFC已经编译成静态LIB和动态LIB,同时,为方便调试,微软将MFC源码(CPP文件)也放到VC里一起发布了;这里会存在两种情陆尺况,如果是静态LIB,那么功能代码会在链接时链接进你的EXE文件中,所以这种静态LIB方式时,EXE文件通常都比较大;如果是动态LIB的方式,那么运行的时候就需要mfcxxx.dll文件,但EXE文件体积比较小
2、如果你理解了1,我再进一步解释,MFC工程配置的时候默认会链接mfcxxx.lib的,所以你的工程里只需要包含对应的头文件,例如 afxxxx.h之类的文件即可,编译器在编译阶段是不需要知道具体实现代码在哪里的,它只需要知道声明即可编译通过,同时编译器会将那些外部的函数(即不是在当前CPP文件实现的函数)标记为需要修复的(我们先把它叫做修复吧);那么,假如我用了一个MFC的函数,现在我只有声明,它是怎么找到具体的实现代码呢,这就是链接器的工作了,刚才我说过,MFC工码悉判程默认是会链接mfcxxx.lib的,所以链接器在工作的时候,它会遍历所有编译过的文件,从里面找出要修复的项,然后再遍历LIB文件,如果在LIB文件里找到对应的实现,那么链接器会把编译阶段留下的手尾FIX掉
3、如果你理解了2,我们再进一步解释2;链接器链接LIB的时候,会有两种情况,第一种,这个LIB本身是一个静态LIB,包含了具体的实现;第二种,这个LIB本身只是一个中介,它是指向DLL的某个函数的;对于第一种情况,链接器会把用到的所有代码链接进去,注意,在Release版本情况下,链接器只会把用的的函数链进去,就是说,即使你的静态LIB有10MB,你也不需要担心编译出来的EXE有10MB,它只会把用到的函数链进去;;对于第二种,是指向DLL某个函数的,链接器会迟改在EXE的PE部里的导入表部分,增加一个项,这个项指向DLL的函数,同时在修复编译阶段留下手尾的地方,让它JMP(跳转)或CALL(调用)到我们DLL函数里
以上纯属个人解释,因为在编译链接阶段是非常复杂的,一时间没办法完全解决齐,有问题可以继续追问
展开全部
你的理解基本正确。
头文件里不一定都是声明,还有更多的毁源竖是库函数等。包含了头文件你写的函数或常量在编译时就能找到定义实例了。头文件主要是一些ASCII文件,编译时打纤大开包含了的文件,比如说你在代码中写有printf这年函数,那么编译器就在头文件中查找printf的定义实体(也叫实现),把它一并嵌入你的代码中,就像你自己写了一个printf放在那里,然后与你的代码一起进行编译。不包含相关的头文件,编译器就不认识你代码中的printf是啥东西,就要报错。编译完成后,那些头文件就关闭了,编译后的文件中只包括了你的代码中需要的部分,所以是很经济裂州的。当然,编译过程比这复杂一些,这里只简单说了一下关于头文件的事。
头文件里不一定都是声明,还有更多的毁源竖是库函数等。包含了头文件你写的函数或常量在编译时就能找到定义实例了。头文件主要是一些ASCII文件,编译时打纤大开包含了的文件,比如说你在代码中写有printf这年函数,那么编译器就在头文件中查找printf的定义实体(也叫实现),把它一并嵌入你的代码中,就像你自己写了一个printf放在那里,然后与你的代码一起进行编译。不包含相关的头文件,编译器就不认识你代码中的printf是啥东西,就要报错。编译完成后,那些头文件就关闭了,编译后的文件中只包括了你的代码中需要的部分,所以是很经济裂州的。当然,编译过程比这复杂一些,这里只简单说了一下关于头文件的事。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
头文件里不一般只有碰御声明么?
一般来说头文件只有声明,但不是绝对的。
include了声明之后,编译器就能自动找到这些声名的实现代码?
并不一定要找到实现肆神代码,而是找到它的实现(一般不是你自己写的代码它的实现都在静态库中(.lib))。vs在编译的时候会连接很多静态库以及动态库裂吵亏(.dll)
一般来说头文件只有声明,但不是绝对的。
include了声明之后,编译器就能自动找到这些声名的实现代码?
并不一定要找到实现肆神代码,而是找到它的实现(一般不是你自己写的代码它的实现都在静态库中(.lib))。vs在编译的时候会连接很多静态库以及动态库裂吵亏(.dll)
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
实现一般都放在库文件里,每州册困次你编译build时候都会链接册念这些库的。
编译链接器通常会默认链接姿模标准库的。
编译链接器通常会默认链接姿模标准库的。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
你可以看一下预编译的概念,MFC中的stdafx.h就是这种预编译头,它用到的头和库基本都包含了
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询