包含C ++ / C头文件的实现在哪里?

时间:2016-12-29 14:30:11

标签: c++ c compilation header-files libraries

这可能看起来有点愚蠢:)但它已经困扰了一段时间。当我在C ++ / C程序中包含一些由其他人编写的头文件时,编译器如何知道头文件中声明的类成员函数的实现在哪里?

说我想写一些利用OpenCV库的程序。通常我会想要使用:

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

但是,这些只是头文件,据我所知,它只声明函数但没有实现。然后编译器如何知道在哪里找到实现?特别是当我想构建.so文件时。

There is a similar post.基本上它说第三方库,尤其是商业产品不发布源代码,因此他们将lib文件与头文件一起发送。但是,它没有说清楚编译器如何知道在哪里找到lib文件。另外,那个帖子中的答案提到如果我想编译自己的代码,我需要这些头文件的执行源代码。这是否意味着我无法在没有实现源的情况下构建.so文件?

4 个答案:

答案 0 :(得分:5)

通常,实现预编译库的形式分发。您需要告诉编译器它们的位置。

例如,对于gcc,引用online manual

-llibrary
-l library
     

链接时搜索名为 library 的库。 [...]

-Ldir
     

将目录 dir 添加到要搜索-l的目录列表中。

注意:您不需要显式指定标准库,它们会自动链接。相反,如果不希望将它们与二进制文件链接,则需要通过传递-nostdlib选项来通知编译器。

答案 1 :(得分:0)

确切的答案是特定于平台的,但一般来说我会说某些库实际上只是头文件,其他库包括在二进制目标文件中实现库的方法。我相信OpenCV属于第二种类型,即提供目标文件中的实现,用于动态或静态链接,并且您的程序链接它们。如果您的构建有效,那么它已经配置为链接这些库。在这一点上,细节变得非常平台和特定于构建系统。

请注意,对于Windows,Mac和Linux等常见平台,您很少需要自己构建像OpenCV这样的流行库。你提到过.so文件,这意味着Linux上的动态链接。这个库是开源的,所以理论上你可以自己构建它,但实际上我宁愿使用我的发行版的软件包安装工具(例如apt-get或yum)从我的发行版中安装opencv-dev(或类似的东西)库中。

答案 2 :(得分:0)

正如其他人已经解释的那样,您需要告诉编译器在哪里查找文件。 这意味着您应该知道为编译器指定的路径。

某些组件提供了一种机制,您无需知道完全路径,但可以自动从系统中检索它。

例如,如果要使用GTK + 3进行编译,则需要为编译器指定这些标志:

  

CFLAGS:= -I ./`pkg-config --cflags gtk + -3.0`

     

LIBS:= -lm`pkg-config --libs gtk + -3.0`

这将自动生成GCC所需的包含和库路径标记。

答案 3 :(得分:-1)

编译器工具链至少包含两个主要工具:编译器和链接编辑器(将编译器命名为整个链很常见,但严格来说这是错误的。)

编译器负责从可用的源代码生成目标代码。在该阶段,编译器知道在何处定位标准头,并且可以被告知使用非标准目录来定位头。例如,gcc使用-I来指定一些可能包含标题的备用目录。

链接编辑器负责从目标代码生成可执行文件(其基本常见用法)。要生成可执行文件,它需要在编译时找到所声明事物的每个实现,而您没有提供源代码。这些可以是其他目标代码,库中的目标代码等。链接编辑器知道标准库的位置,并且可以告诉您指定非标准目录。例如,您可以告诉gcc工具链使用可能包含库的L的备用目录。您可能知道链接版本现在通常是一个两阶段过程:链接时的位置和名称解析以及运行时的实际链接版本(动态库非常常见)。

基本上,库只是对象代码的集合。请咨询互联网,了解如何从目标代码的源代码轻松构建库。