在一个 C++ 工程中,并不是所有代码都会编译成可执行文件。只有带有 main 函数的文件才会生成可执行程序。而另一些代码,我们只想把它们打包成一个东西,供其他程序调用。这个东西叫做库。
如何加入库文件
——以库文件libHelloSLAM.cpp举例
1.生成库(静态库)
//这是一个库文件
#include
using namespace std;
void printHello()
{
cout<<“Hello SLAM”<}
这个库提供了一个 printHello 函数,调用此函数将输出一个信息。但是它没有 main函数,这意味着这个库中没有可执行文件。
我们在 CMakeLists.txt 里加一句:
add_library( hello libHelloSLAM.cpp )
这条命令告诉 cmake,我想把这个文件编译成一个叫做“hello”的库。然后使用 cmake 编译整个工程:
cd build
cmake …
make
这时,在 build 文件夹中会生成一个 libhello.a 文件,这就是我们得到的库。
2.共享库
在 Linux 中, 库文件分成静态库和共享库两种。静态库以.a 作为后缀名,共享库以.so结尾。所有库都是一些函数打包后的集合,差别在于静态库每次被调用都会生成一个副本,而共享库则只有一个副本,更省空间。如果我们想生成共享库而不是静态库,只需用:
add_library( hello_shared SHARED libHelloSLAM.cpp )
就可以编译成一个共享库。此时得到的文件是 libhello_shared.so 了。
库文件是一个压缩包,里头带有编译好的二进制函数。不过,仅有.a 或.so 库文件的话,我们并不知道它里头的函数到底是什么,调用的形式又是什么样的。
为了让别人(或者自己)使用这个库,我们需要提供一个头文件,说明这些库里都有些什么。因此,对于库的使用者,只要拿到了头文件和库文件,就可以调用这个库了。
3.调用库
libhello的头文件libHelloSLAM.h
#ifndef LIBHELLOSLAM_H_
#define LIBHELLOSLAM_H_
void printHello();
#endif
编写可执行程序
useHello.cpp
#include “libHelloSLAM.h”
int main( int argc, char** argv )
{
printHello();
return 0;
}
CMakeLists.txt调用库文件
添加一个可执行程序的生成命令,链接到刚才我们使用的库上:
add_executable( useHello useHello.cpp )
target_link_libraries( useHello hello_shared )
通过这两句话, useHello 程序就能顺利使用 hello_shared 库中的代码了。
这个小例子演示了如何生成并调用一个库。
请注意对于他人提供的库,我们也可用同样的方式对它们进行调用,整合到自己的程序中。
4.总结
#添加库add_library( 库名 库的类型 库文件cpp文件 )
add_library( hello_shared SHARED libHelloSLAM.cpp )
#可执行文件
add_executable( useHello useHello.cpp )
#可执行文件链接库target_link_libraries( 可执行文件名 库名 )
target_link_libraries( useHello hello_shared )
参考:《视觉SLAM十四讲》