如何使用带有标头和 .so 文件的库

How to use a library with headers and .so files?

本文关键字:so 文件 何使用      更新时间:2023-10-16

我是C的新手,想使用一个库(MLT多媒体框架(

我已经构建了它,它产生了以下目录:include lib share

里面lib.so .a .la文件
里面include.h文件

现在,我被指示这样做:

#include <framework/mlt.h>在里面include/mlt/framework/

问题:

  • 为什么我需要放置仅包含函数原型的头文件?那么真正的功能在哪里呢?它们是否以某种方式链接到目录中lib内容?
  • 在哪里放置我自己的文件以及如何编译它
  • 如何了解有关这些主题的更多信息:
    • 动态/静态库
    • 建造/制作/安装
    • 如何使用任何 C 库

如果您没有函数原型,编译器如何知道库中存在哪些函数?简短的回答是:它没有。更长的答案:编译器不关心库文件,静态(以.a结尾的文件(或共享(以.so结尾的文件(,它关心的只是当前的翻译单元。由链接器来处理解析未定义的引用。

使用库时,将包含所需声明(结构、类、类型、函数原型(的头文件包含在源文件中。源文件加上所有包含的头文件构成了编译器用于生成代码的翻译单元。如果存在未定义的引用(例如,对库中函数的调用(,编译器会将有关该引用的特殊信息添加到生成的对象文件中。然后,链接器会查看所有对象文件,如果找到未解析的引用,它将尝试在其他对象文件和提供的库中查找该引用。如果解析了所有定义,链接器将生成最终的可执行文件,否则它将未解析的定义报告为错误。


要回答您的其他问题:

在哪里放置我自己的文件以及如何编译它?

这是两个问题,第一个问题(关于文件的位置(的答案是这并不重要。对于只有几个源文件和头文件的小型项目,通常将所有文件放在一个公共项目目录中。

第二个问题,关于编译,也有不同的方法可以做到。如果只有一个或两个源文件,您可以使用编译器前端(例如 gcc ( 一次性编译、链接和生成可执行文件:

$ gcc -Wall -g source1.c source2.c -o your_program_name

上面的命令需要两个源文件,编译并将它们链接到程序your_program_name中。

如果您需要使用库,则需要在上述命令行中添加一两件事:

  1. 您需要告诉链接器与库链接,例如使用-l(小写 L(选项完成:

    $ gcc -Wall -g source1.c source2.c -o your_program_name -lthe_library
    

    请务必注意,the_library是库的基本名称。如果库文件命名为 libthe_library.so则只需要the_library部件,链接器将自动添加其他部件。

  2. 如果库不在标准位置,则需要告诉编译器和链接器库文件的位置。这是通过 -I(大写 i(选项完成的,该选项告诉预处理器头文件的位置,以及链接器文件所在的-L(大写 l(。

    类似的东西

    $ gcc -Wall -g -Ilocation/of/headers source1.c source2.c -o your_program_name -Llocation/of/libraries -lthe_library
    
如果您有多个源文件,

通常使用所谓的 makefile,其中列出了所有源文件、其依赖项、编译器和链接器标志,并包含有关如何生成目标文件和链接最终程序的规则。这样的生成文件可能看起来像

CFLAGS  = -Wall -g
LDFLAGS = -g
SOURCES = source1.c source2.c
OBJECTS = $(SOURCES:.c=.o)
TARGET  = your_program_name
.PHONY: all
all: $(TARGET)
$(TARGET): $(OBJECTS)
    $(LD) $(LDFLAGS) $^ -o $@
%.o: %.c
    $(CC) $(CFLAGS) $< -c -o $@

上面的生成文件应该与前面的命令行几乎相同。最大的区别在于,添加更多源文件、为特殊文件添加特殊规则要容易得多,最重要的是,make 程序将处理依赖项,因此如果一个源文件自上次构建以来未被修改,则不会对其进行编译。最后一点将使具有许多源文件的大型项目在仅修改一个或几个源文件时构建得更快。


如何了解有关主题的更多信息 [...]

通过转到您最喜欢的搜索引擎,并在那里寻找这些主题。我也推荐例如维基百科。


当然,如果您使用集成开发环境(也称为 IDE(,则不必从命令行进行编译或创建自己的生成文件,IDE 将为您处理所有这些。它还将具有项目设置的对话框,您可以在其中输入包括路径和库路径,以及要链接的库。

为什么我需要放置仅包含函数原型的头文件?

以满足编译器声明这些函数或类声明的要求。由于C++静态类型检查语言,他们必须知道他们将使用的对象类型。

在哪里放置我自己的文件以及如何编译它?

您可以将代码放在文件系统中的任何位置;只需确保在编译时将 .h 文件包含在 include path 和 lib 中。通常您需要修改路径。

您可以在此链接上查看有关构建的信息:

https://en.wikipedia.org/wiki/GNU_build_system

检查代码附带的README文件。 它应该告诉您如何将其正确安装到系统中。 通常有一个install构建目标,它将生成的文件安装到正确的目录中。

构建和安装大多数产品的常用命令顺序是:

$ ./configure
$ make
$ sudo make install