0

我按照以下教程创建了一个静态库。

http://tldp.org/HOWTO/Program-Library-HOWTO/static-libraries.html

http://www.adp-gmbh.ch/cpp/gcc/create_lib.html

http://www.cs.dartmouth.edu/~campbell/cs50/buildlib.html

ar我使用该工具在 C 中生成了一个静态库。该库来自不同的目录。我正在正确生成库,并使用它来编译我的程序,如下所示:

gcc -lpthreads main.c -o server -L thread-pool -lthreadpool

调用当前目录下的库,thread-pool其中包含libthreadpool.a.

根据教程,我需要将我的文件包含在:.h中,如下所示。GCC 抛出一个错误,说没有找到。这很明显,因为它位于不同的目录中。main.c#include "threadpool.h"threadpool.h

当我包含时:#include threadpool/threadpool.h"它可以编译但实际上不起作用。它仍然无法识别这些功能。我不确定为什么会这样。我认为在编译静态库时,实际上您不需要实际发送.h文件或任何源。

这里有什么问题?我该如何克服呢?

编辑:

我知道 .h 文件与静态库不同。我不知道为什么我上面所说的似乎让我在两者之间感到困惑。

无论如何,当使用静态库时,是否意味着我们也需要该.h文件并将其包含到源代码中,而不仅仅是使用静态库编译程序?

4

2 回答 2

4

库和标题是两个不同(尽管相关)的东西。您还可以通过编译器的选项解决您的问题,为编译器提供一个额外的目录来查找头文件:

gcc -lpthreads -I threadpool main.c -o server -L thread-pool -lthreadpool

由于您的threadpool库可能依赖于libpthread,您可能需要更改编译器命令行,以便避免出现链接问题libpthreadslibthreadpool

gcc -I threadpool main.c -o server -L thread-pool -lthreadpool -lpthreads

实际上,首选选项是使用-pthread确保 pthread 库正确链接的选项,并且完成线程支持所需的任何其他编译器配置(-pthread选项的顺序似乎无关紧要):

gcc -pthread -I threadpool main.c -o server -L thread-pool -lthreadpool

-lxyz在任何目标文件之后而不是在它们之前列出库(例如)也是一个好主意。在某些系统上,它可以双向工作;在所有已知系统上,在目标文件之后列出库总是有效的。

于 2012-12-02T01:58:54.310 回答
2

正如Michael Burr 所说,.h 文件的#include 以及与库文件的链接是两个不同(但相关)的东西。

当您构建一个由多个部分(例如多个 .c 源文件或库)组成的 C 程序时,该过程分两步完成。首先编译各个源 .c 文件,即将 C 源文件翻译成可执行机器指令的模块。然后将程序所需的所有模块和库链接在一起,构建可执行文件。

静态链接和动态链接之间的区别只是链接完成的时间。从概念上讲,它们是相同的东西,但是静态链接(带有静态库)是提前完成的,形成一个可以稍后运行的可执行文件,而动态链接是在执行前立即完成的。

链接的类型(静态或动态)根本不影响编译步骤。

在编译单个源文件期间,编译器需要为调用库函数生成代码。例如,如果一个库包含一个以 double 作为参数的函数 f,而源文件包含代码 f(7),编译器需要知道有一个名为 f 的函数,并且它需要一个 double 作为参数,因此编译器可以在实际调用函数 f 之前生成将整数 7 转换为双精度的代码。

这是通过将函数声明放在 .h 文件中来完成的,然后将其包含在您的 .c 源文件中。例如,该声明可能如下所示:

void f(double);

这使得编译器能够生成正确的代码,并在出现错误时给出正确的警告和错误消息。

另一方面,该库包含已编译的函数定义,它是执行某些操作的函数的实际代码。

请注意,编译步骤与库文件几乎没有关系,与静态或动态链接的区别无关。为了能够#include .h 文件,编译器需要知道在哪里可以找到 .h 文件。这可能与实际的库文件完全不同。库文件甚至不必存在于同一台计算机上,甚至根本不存在。执行#include 时,库中的实际函数可能尚未编写。

混淆的一个来源可能是 gcc 命令,

gcc -lpthreads main.c -o server -L thread-pool -lthreadpool

看起来它同时执行编译和链接。确实如此,但这只是为了方便,在幕后它仍然分两个单独的步骤完成。

于 2012-12-02T02:26:33.730 回答