如何使用带有标头和 .so 文件的库
How to use a library with headers and .so files?
我是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
中。
如果您需要使用库,则需要在上述命令行中添加一两件事:
您需要告诉链接器与库链接,例如使用
-l
(小写 L(选项完成:$ gcc -Wall -g source1.c source2.c -o your_program_name -lthe_library
请务必注意,
the_library
是库的基本名称。如果库文件命名为libthe_library.so
则只需要the_library
部件,链接器将自动添加其他部件。如果库不在标准位置,则需要告诉编译器和链接器库文件的位置。这是通过
-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
- 如何使用ndk-build.cmd构建Android.so文件
- 在C++代码中包含opencv时,使用ctypes创建.so文件
- 用于构建 cuda .so 文件(共享库)的生成文件
- 无法从 SO 文件调用 SO 文件的函数 - C++生成文件
- 如何在 C++ 的 .so 文件中包含库
- JNI,使用两个 .so 文件时出错,其中一个文件需要另一个文件
- Google Colab 看不到 .so 文件
- 如何在 Linux 中从 .so 文件打开可执行文件?
- 如何在makefile中包含tensorflow c ++".so"文件?
- 缺少 .h 文件,尽管从库文件夹链接了 .so 文件
- 如何在 CMake 超级生成中查找 dll/so 文件
- 如何用.so文件linux打包所有需要的库
- 如何调试visual studio 2017生成的C++代码.android中的SO文件和其他第三方库
- 从多个C++文件生成 .so 文件并使用它
- .so 文件无法"see"编译时使用的库
- 从 .so/.o 文件中获取 C/cpp 中的静态库列表
- 在Windows上运行Linux Makefile(.so文件)
- 如何静态链接到 POCO C++ so 文件
- C++ .so 文件中的模板化函数
- 卸载共享对象(.so 文件)在 C++ 中用 dlopen() 打开