将'.h'导入'.m'文件后,它们是否永远链接?

时间:2011-02-12 16:53:27

标签: objective-c header implementation

我有一个CarClass.h文件,声明CarClass 然后我#import将此CarClass.h文件放入我的CarClass.m文件中,然后我继续执行所有CarClass方法。
最后,我的CarAPP.m文件(其中包含main)也#imports CarClass.h - 一切正常。

那里实际上没有问题: - )

但是,我不确定我理解为什么它有效 - 因为链接似乎有点偏离:如果CarAPP.m仅导入CarClass.h文件 - 而不导入CarClass.m文件,然后从哪里获取或查看实现? 是这样的情况,一旦导入“.h”文件的“.m”文件被编译,那么两个文件(.h和.m)是排序永远链接的还是什么? 我只是不明白......

2 个答案:

答案 0 :(得分:1)

编译过程分为不同的阶段,#import指令在任何链接发生之​​前很久就被解释。

当您将代码文件(.c,.m)提供给编译器时,它将尝试从中生成代码对象文件(.o);也就是代码的二进制表示。此文件尚不可执行,因为它需要更多信息。特别是,它没有链接到任何其他文件。头文件,应该只包含声明而没有定义,通常不会得到自己的匹配.o文件。

在将所有代码文件转换为代码对象之后,编译器会将它们放在一起并调用链接器。链接器将解析所有外部引用,然后生成可执行文件。

重点是头文件告诉编译器存在某个的函数或方法。在编译的当前阶段,这足以生成目标文件:编译器只需要告知存在的内容,而不是定义的位置。只有当你真正链接时,你需要知道这一点。

由于所有代码对象文件都打包在一起,因此整个程序可以访问本身公开声明的所有内容。这就是为什么您不需要将CarAPP.m明确地“链接”到CarClass.m。

也可能误导编译器并在未在任何地方定义的头文件中声明函数。如果你在你的程序中使用它们,编译的第一阶段就会很好(没有语法错误,没有“未声明的函数”)但它会在链接时断开,因为链接器将无法找到不存在的函数

答案 1 :(得分:0)

当您有#import whatEver.h时,预处理器会尝试在默认位置找到相应的文件。如果找到,它只会将whatEver.h的内容粘贴到您使用#import whatEver.h的相应源文件中。因此,要获得最终的可执行文件,源文件应该通过Pre-Process,Compile和Linker阶段。

CarClass.h中有CarAPP.m时,链接器会在CarClass.h中找到CarClass.m的实现。严格地说,它是在CarClass.o中找到定义。编译器很高兴只要有你使用的声明,并且链接器很满意,只要你打算使用声明的定义。

当您将CarClass.h导入CarAPP.m时,您要告诉链接器在CarClass.h中找到CarClass.o方法实现。因此,您的最终可执行文件是CarAPP.oCarClass.o的组合。要了解有关如何完成编译和链接的更多信息,请Program Compilation。虽然链接是特定于C / C ++的,但它应该给你一个想法。