2

我在我的 *.c 程序中使用 GLFW 库。

    #include <GL/glfw.h>
    #include <stdlib.h>

    int main(void)
    {
        int running = GL_TRUE;
        int k=0;
.....
...
..

我用来编译的命令是:

gcc test1.c -o test1 -lglfw

我的问题是,因为存在这条线:

#include <GL/glfw.h>

为什么我必须传递-lglfwgcc

4

3 回答 3

6

GL/glfw.h 是一个头文件,它声明了所有的类型、常量、函数,你懂的,它是为了让编译器知道要生成什么代码,并且让它不会抱怨未知的标识符。libglfw 是一个包含实际二进制代码(或稍后将由动态链接器绑定的存根,或类似的东西)的库,您必须与它链接以使链接器不会抱怨未解析的符号。

标头可能包含库的实际代码(因此编译器会为使用该库的每个翻译单元一遍又一遍地生成二进制代码),那时它被称为仅标头库,但在C 世界中这样的库不是您经常可以找到的,而且这个特定的库不是仅标题的。

于 2011-10-26T13:39:24.683 回答
1

我不具体了解 GLFW 库。但是,它是编译器#include的预处理器指令(如果您错过它,您的代码将无法编译),但参数是针对链接器的(如果您错过它,代码将被编译为目标文件,但您会通过链接器获取未定义的符号)。-lglfw

一些(罕见的)库只是标题的东西;它们完全在#include-d 标头中提供功能。我只知道一个这样的库(GNU 闪电)。

大多数库以共享或静态库文件(即lib*.solib*.a文件)的形式存在。它们提供已编译代码的功能,您需要链接到可执行文件中。

阅读有关链接器的更多信息

于 2011-10-26T13:42:12.190 回答
1

好吧,头文件(带有 .h 的)只包含 say 函数、变量类等的声明。因此,通过在 .c 文件中包含头文件,您可以使编译器知道函数等的声明。这意味着,编译器能够生成实际调用函数的命令。

但是,函数的定义(即实际实现)是完全不同的东西,并且它(通常)存在于标头中(仅包含声明)。

因此,为了真正调用实现,目标代码(即编译的源代码)也必须存在于可执行文件中。但是,此代码包含在外部库(在您的情况下为 libglfw.a)中。因此,通过添加 -lglfw 选项,您可以将库中包含的目标代码添加到可执行文件中,从而确保您从代码中进行的调用最终会进入库代码。

底线:*.h 文件 -> 仅声明,无实现

*.cpp, *.o, .a(.lib), .so(.dll, .dynlib) -> 目标代码,实现

于 2011-10-26T13:42:59.673 回答