简体   繁体   English

需要澄清在iOS中链接库时发生了什么

[英]Need clarification on what's going on when linking libraries in iOS

This is probably a totally noob question but I have missing links in my mind when thinking about linking libraries in iOS. 这可能是一个完全没有问题的问题,但是在考虑链接iOS中的库时,我脑海中缺少链接。 I usually just add a new library that's been cross compiled and set the build and linker paths without really know what I'm doing. 我通常只是添加一个经过交叉编译的新库,并设置构建和链接器路径,而实际上并不知道我在做什么。 I'm hoping someone can help me fill in some gaps. 我希望有人可以帮助我填补一些空白。

Let's take the OpenCV library for instance. 让我们以OpenCV库为例。 I have this totally working btw because of a really well written tutorial( http://niw.at/articles/2009/03/14/using-opencv-on-iphone/en ), but I'm just wanting to know what is exactly going on. 由于编写了非常好的教程( http://niw.at/articles/2009/03/14/using-opencv-on-iphone/zh-CN ),我的工作完全正常,但是我只是想知道什么到底是怎么回事。

What I'm thinking is happening is that when I build OpenCV for iOS is that your creating object code that gets placed in the .a files. 我正在想的是,当我为iOS构建OpenCV时,是将创建的目标代码放入.a文件中。 This object code is just the implementation files( .m ) compiled. 此目标代码只是编译的实现文件(.m)。 One reason you would want to do this is to make it hard to see the source code and so that you don't have to compile that source code every time. 您要执行此操作的原因之一是使其难以查看源代码,从而不必每次都编译该源代码。

The .h files won't be put in the library ( .a ). .h文件不会放入库(.a)。 You include the .h in your source files and these header files communicate with the object code library ( .a ) in some way. 在源文件中包括.h,这些头文件以某种方式与目标代码库(.a)通信。

You also have to include the header files for your library in the Build Path and the Library itself in the Linker Path. 您还必须在构建路径中包含库的头文件,在链接程序路径中包含库本身。

So, is the way I view linking libraries correct? 那么,我查看链接库的方式是否正确? If , not can someone correct me on this ? 如果可以,有人可以对此进行纠正吗?

Basically, you are correct. 基本上,您是对的。

Compiling the source code of a library produces one object file for each of the source files (in more than one, if compiled multiply times against different architectures). 编译库的源代码会为每个源文件生成一个目标文件(如果针对不同体系结构编译乘以倍数,则将生成多个目标文件)。 Then all the object files are archived (or packaged) into one .a file (or .lib on Windows). 然后,所有目标文件都被存档(或打包)到一个.a文件(或Windows中的.lib)中。 The code is not yet linked at this stage. 该代码目前尚未链接。

The .h files provide an interface for the functionality exposed by the library. .h文件为库公开的功能提供了接口。 They contain constants, function prototypes, possibly global declarations (eg extern int bad_global; ), etc. -- basically, everything that is required to compile the code which is using the library. 它们包含常量,函数原型,可能还包含全局声明(例如, extern int bad_global; )等-基本上,这是编译使用库的代码所需的一切。

.h files do not 'communicate' with object code in any way. .h文件不会以任何方式与目标代码“通信”。 They simply provide clues for the compiler. 它们只是为编译器提供了线索。 Consider this header file: 考虑以下头文件:

// library.h

extern int bad_global;

int public_func(int, const void*);

By including this file in your own code, you're simply telling the compiler to copy and paste these declarations into your source file. 通过将此文件包含在自己的代码中,您只是在告诉编译器将这些声明复制并粘贴到源文件中。 You could have written declarations for OpenCV library and not use the headers provided with it. 您可能已经为OpenCV库编写了声明,而不使用它随附的标头。 In other words, you're asking the compiler to not issue errors about undefined symbols, saying "I have those symbols elsewhere, ok? Here are their declarations, now leave me alone!". 换句话说,您是在要求编译器不要发布有关未定义符号的错误,说“我在其他地方有这些符号,好吗?这是它们的声明,现在让我一个人!”。

The header files need to be included in the search path in order for compiler to find them. 头文件需要包含在搜索路径中,以便编译器找到它们。 You could simply include them via the full path, eg #include "path/to/file.h" , or supply an -I option for your compiler, telling him where to look for additional headers, and use #include <file.h> instead. 您可以简单地通过完整路径将它们包括在内,例如#include "path/to/file.h" ,或者为您的编译器提供-I选项,告诉他在哪里寻找其他头文件,并使用#include <file.h>代替。

When your code is compiled, the declarations in header files serve as an indication that symbols your code is using are defined somewhere. 编译代码时,头文件中的声明表示在某些地方定义了代码所使用的符号。 Note the difference between the words declaration and definition . 注意声明定义之间的区别。 Header files contain only declarations most of the time. 头文件大多数时候只包含声明。

Now, when your code is compiled, it must be linked in order to produce the final executable. 现在,在编译代码时,必须将其链接以便生成最终的可执行文件。 This is where the actual object code stored in the library comes into play. 这是存储在库中的实际目标代码起作用的地方。 The linker will look at each symbol, function call, etc. in your object code and then try to find the corresponding definition for each such symbol. 链接器将查看目标代码中的每个符号,函数调用等,然后尝试为每个此类符号找到相应的定义 If it doesn't find one in the object code of your program, it will look the standard library and any other library you've provided it with. 如果在程序的目标代码中找不到一个,它将查找标准库以及您提供的任何其他库。

Thus, it is important to understand that compilation and linkage are two separate stages. 因此,重要的是要理解编译链接是两个单独的阶段。 You could write any function prototypes at all and use them in your code, it will compile cleanly. 您可以编写任何函数原型,并在代码中使用它们,它将干净地编译。 However, when it comes to the linking stage, you have to provide implementation for symbols used in your code, or you won't get your executable. 但是,当涉及到链接阶段时,您必须提供代码中使用的符号的实现,否则将无法获得可执行文件。

Hope that makes sense! 希望有道理!

The .a is the compiled version of the code. .a是代码的编译版本。

The header files provided with a library are its public interface. 库随附的头文件是其公共接口。 They show what classes, methods, properties are available. 它们显示了可用的类,方法和属性。 They do not "communicate" with the binary code. 它们不与二进制代码“通信”。

The compiler needs the headers to know that a symbol (a method name for example) is defined somewhere else. 编译器需要标头知道在其他位置定义了符号(例如,方法名称)。 They are associated with the right "piece of code" in the library binary later during the "link" step. 它们在稍后的“链接”步骤中与库二进制文件中的正确“代码段”相关联。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM