【问题标题】:How do you actually use a C library?您如何实际使用 C 库?
【发布时间】:2010-12-17 11:18:31
【问题描述】:

我确信这个问题已经被问过很多次了,但我无法弄清楚。忍受我。

所以当你下载一个库时,你会得到一堆 .c 和 .h 文件,以及很多其他的东西。现在假设你想使用这个库编写一个程序。

我将所有 .h 文件复制到我的项目目录中。它只是无法编译。

太好了,然后我将库作为一堆 .dll 获取,然后将 dll 复制到我的项目目录中。仍然无法编译。

这是如何工作的?

你会做什么,比如在为你的项目创建文件夹之后?您将库包的哪些部分复制/粘贴到文件夹中?你如何使它可以编译?请和我一起完成这些步骤。

  1. .h 文件放在哪里?
  2. .dll 文件放在哪里?
  3. 如何编译?

谢谢。

(我正在尝试使用的库是 libpng,我在 Windows 中使用 MinGW,我希望像往常一样从命令行编译。)

(据我所知,您将 .h 文件放在目录 A 中,将 .dll 文件放在目录 B 中,您可以使用 -l 和 -L 编译器选项告诉编译器在哪里可以找到它们,这是正确的吗? )

【问题讨论】:

    标签: c windows linker compilation


    【解决方案1】:

    以下是编译和构建基本 C 项目时发生的情况的简要指南:

    • 第一阶段编译所有源文件 - 这将获取您编写的源文件并将它们转换为所谓的目标文件。在这个阶段,编译器需要知道你在代码中使用的所有函数的声明,即使是在外部库中,所以你需要使用#include 来包含你使用的任何库的头文件。 这也意味着您需要告诉编译器这些头文件的位置。使用GCC,您可以使用-I 命令行输入要搜索头文件的目录。 p>

    • 下一阶段是将所有目标文件链接到一个可执行文件中。在这个阶段,链接器需要解析对外部库的调用。 这意味着您需要对象形式的库。 大多数库都会为您提供有关如何生成此库的说明,或者可能会提供已构建好的库。在 Linux 下,库文件通常是 .a.so 文件,尽管它可能只是 .o。同样,您可以使用 -L 选项将库的目标文件的位置提供给 GCC。

    因此您的命令行将如下所示:

    gcc myProg.c -I/path/to/libpng/include -L/path/to/libpng/lib -lpng -o myProg.exe
    

    (请注意,当使用-l 命令行时,GCC 会自动将lib 添加到库的开头,因此-lpng 会导致libpng.a 被链接。)

    希望对您有所帮助。

    【讨论】:

    • 这家伙显然是新手,询问 DLL 文件 (Windoze),你告诉他使用 .a 文件的 GCC 吗?
    【解决方案2】:

    在 windows 下执行(假设您使用 Visual Studio)

    • 解压后将库包含目录添加到项目设置中(项目 -> 属性 -> C/C++ -> 附加包含目录)

    • 对库目录执行相同的操作(项目 -> 属性 -> 链接器 -> 其他库目录)

    • 在链接器输入中指定库的名称:项目 -> 属性 -> 链接器 -> 输入 -> 附加依赖项

    在此之后希望应该编译。

    我不建议将上面的目录添加到 Visual Studio 中的全局设置(工具 -> 选项 -> 项目和解决方案),因为它会创建一个环境,让某些东西在您的计算机上编译,而不是在另一台计算机上编译。

    现在,困难的方法是为基于 Makefile 的构建系统做这件事:

    • 拆开你的东西
    • 在 -I g++ 标志下指定包含目录
    • 在 -L g++ 标志下指定库目录
    • 指定要使用的库,例如:-llibrary 名称(例如:-lxml2 用于 libxml2.so)
    • 指定静态库,如:library name.a

    最后你应该有一个丑陋的命令,看起来像:

    g++ -I/work/my_library/include -L/work/my_library/lib -lmylib my_static.a -o appname_exe MYFILE.CPP

    (上面这行并没有真正测试,只是一个大概的想法)

    我建议去,从某个地方获取一个模板 makefile 并添加你所有的东西。

    【讨论】:

    • 有一个非常方便的 makefile 模板:jukie.net/~bart/blog/makefile-template。抓住它,完成它,当你填满所有必需的数据后,只需“制作”它
    • 非常感谢,您的回答真是天赐良机。终于有人逐步解释了如何在 C 中进行操作。如果您像我一样不熟悉编程和 Visual Studio,那么很难找到这些设置。
    【解决方案3】:

    您必须链接到 .lib 或类似的东西,即将“.lib”添加到链接器读取的库中。至少它在 Linux 下是这样工作的……很久没做过 Windows 了。

    “.lib”包含 .dll 共享库中数据/函数的符号。

    【讨论】:

    • 您使用的是什么编译器/链接器?
    • ...当我第一次回答这个问题时,没有提到 MinGW。
    【解决方案4】:

    这取决于库。例如,一些库包含预编译的二进制文件(例如 dll),而其他库则需要您自己编译。你最好看看图书馆的文档。

    基本上,要编译,您应该:

    (1) 在编译器的包含路径中包含库的包含 (.h) 文件位置,

    (2) 在链接器的库路径中包含库存根 (.lib) 位置,并让链接器引用相关的库文件。

    为了运行程序,您需要拥有加载程序可以看到它们的共享库 (dll),例如在您的 system32 目录中。

    【讨论】:

      【解决方案5】:

      有两种库:静态和动态(或共享)。

      静态库采用对象格式,您可以将它们直接链接到您的应用程序中。

      共享或动态库驻留在单独的文件(.dll 或 .so)中,该文件在您的应用程序运行时必须存在。它们还附带您必须链接到您的应用程序的目标文件,但在这种情况下,它们只包含查找和调用运行时二进制文件(.dll 或 .so)的存根。

      在任何一种情况下,您都必须有一些包含库函数签名(声明)的头文件,否则您的代码将无法编译。

      有些“库”只有标头,您只需包含它们即可。有些由头文件和源文件组成。在这种情况下,您应该针对您的应用程序编译和链接源代码,就像处理您编写的源文件一样。

      【讨论】:

        【解决方案6】:

        当你编译时,假设你的库和头文件与你正在编译的源代码在同一个文件夹中,你需要添加到你的编译行-L . -I . -lpng。 -L 告诉链接器在哪里寻找库,-I 告诉编译器在哪里寻找头文件,-lpng 告诉链接器与 png 库链接。

        [编辑] 普通项目将具有某种层次结构,其中标头位于 /include 文件夹中,而第 3 方库位于 /libs 文件夹中。在这种情况下,您应该使用 -I ./include-L ./libs 而不是 -I .-L.

        [Edit2] 大多数项目使用 makefile 来从命令行编译。您只能手动编译少量文件,之后会变得很忙

        【讨论】:

        • 您不需要这些来源。您需要库文件(.lib 或 .a)。我不确定如何处理 dll。
        【解决方案7】:

        另外,
        您可能想查看Dynamic Loading 支持各种语言和各种 平台。
        当您想选择性地使用某个库并且您不希望您的程序在该库不可用的情况下失败时,这种支持非常方便。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2023-02-24
          • 2018-05-16
          • 2017-11-18
          • 2017-03-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多