你如何实际使用C库?

时间:2009-11-17 13:58:12

标签: c windows linker compilation

我确信这个问题已被多次询问过,但我无法弄清楚这一点。忍受我。

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

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

很好,所以我把这个库作为一堆.dll的,我将dll复制到我的项目目录中。仍然没有编译。

这是如何运作的?

您在为项目创建文件夹后立即做了什么?您将库包的哪些部分复制/粘贴到文件夹中?你是怎么做到它可以编译的?请跟我一起完成这些步骤。

  1. 放置.h文件的位置?
  2. 放置.dll文件的位置?
  3. 如何编译?
  4. 感谢。

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

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

7 个答案:

答案 0 :(得分:12)

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

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

  • 下一步是将所有目标文件链接到一个可执行文件中。在此阶段,链接器需要解析对外部库的调用。 这意味着您需要以对象形式存储库。大多数库将为您提供有关如何生成此库或可能为其提供现成的库的说明。在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被链接。)< / p>

希望有所帮助。

答案 1 :(得分:7)

在Windows下进行(假设您使用Visual Studio)

  • 解压缩后,将库包含目录添加到项目设置中(项目 - >属性 - &gt; C / C ++ - &gt;其他包含目录)

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

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

此后希望编译。

我不建议将上面的目录添加到Visual Studio中的全局设置(工具 - &gt;选项 - &gt;项目和解决方案),因为它将创建和环境,在您的计算机上编译某些内容并且不在另一个上编译之一。

现在,艰难的方法,为基于Makefile的构建系统做到这一点:

  • 打开你的东西
  • 指定-I g ++标志
  • 下的include目录
  • 指定-L g ++标志
  • 下的Library目录
  • 指定要使用的库,如:-llibrary name(例如:-lxml2 for 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并添加你所有的东西。

答案 2 :(得分:3)

您必须链接.lib或等效的东西,即将“.lib”添加到链接器读取的库中。至少这是它在Linux下的工作方式......很长一段时间没有完成Windows。

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

答案 3 :(得分:2)

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

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

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

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

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

答案 4 :(得分:1)

编译时,假设您的libs和标题位于与您编译的源相同的文件夹中,则需要添加到编译行-L . -I . -lpng。 -L告诉链接器在哪里查找库,-I告诉编译器在哪里查找头文件,-lpng告诉链接器链接到png库。

[编辑] 正常项目将具有某种层次结构,其中标头位于/include文件夹中,第三方库位于/libs文件夹中。在这种情况下,您需要-I ./include-L ./libs而不是-I .-L.

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

答案 5 :(得分:1)

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

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

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

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

某些“图书馆”仅限标题,您只需要包含它们即可。一些包含头文件和源文件。在这种情况下,您应该像编写您编写的源文件一样编译和链接源应用程序。

答案 6 :(得分:0)

另外,
您可能希望查看各种语言和各种语言的Dynamic Loading支持 平台。
如果您希望可选地使用库并且您不希望程序在库不可用时失败,则此支持非常方便。