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

Nau*_*der 11 c c++

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

我已经构建它并生成以下目录: include lib share

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

现在,我被指示这样做:

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

问题:

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

Som*_*ude 17

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

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


回答你的其他问题:

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

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

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

$ gcc -Wall -g source1.c source2.c -o your_program_name
Run Code Online (Sandbox Code Playgroud)

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

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

  1. 您需要告诉链接器链接库,这可以通过例如-l(小写L)选项完成:

    $ gcc -Wall -g source1.c source2.c -o your_program_name -lthe_library
    
    Run Code Online (Sandbox Code Playgroud)

    重要的是要注意这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
    
    Run Code Online (Sandbox Code Playgroud)

如果您有多个源文件,则通常使用所谓的makefile来列出所有源文件,它们的依赖项,编译器和链接器标志,并包含有关如何构建目标文件和链接最终程序的规则.这样的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 $@
Run Code Online (Sandbox Code Playgroud)

上面的makefile应该与上一个命令行大致相同.最大的区别是,添加更多源文件,添加特殊文件的特殊规则要容易得多,最重要的是,make程序将处理依赖关系,这样如果一个源文件自上次构建以来未被修改,那么它将不会编译.当仅修改一个或几个源文件时,最后一点将使具有许多源文件的大项目更快地构建.


如何进一步了解这些主题[...]

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


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


小智 5

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

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

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

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

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

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