【编写库文件+使用库文件】
【编写库文件+使用库文件】
静态库
(1)拓展名.a(Linux) .lib(Windows)
编译时直接连接到可执行文件中
(2)静态库对函数库的链接是放在编译时期完成的
(3)程序在运行时与函数库再无瓜葛,移植方便
动态库
(1)拓展名.so+版本号 eg .so.8.0(Linux) .dll(Windows)
程序运行时动态链接
(2)把对一些库函数的链接载入推迟到程序运行的时期
(3)可以实现进程之间的资源共享 因此动态库也称为共享库
(4)将一些程序升级变得简单,甚至可以真正做到链接载入完全由程序员在程序代码中控制(显示调用)
编译过程
运用gcc指令
例程1
文件准备
hello.cpp
#include <iostream>
void say_hello(char *name)
{
printf("Hello %s\n", name);
}
头文件
hello.h 学习写法!
#ifndef _HELLO_H
#define _HELLO_H
void say_hello(char *name);
#endif
main.c
#include "hello.h"
int main()
{
say_hello("hualai");
return 0;
}
静态库
(1)将.c文件编译为.o文件
执行:gcc -c hello.c
生成hello.o文件
(2)使用ar命令将.o文件打包成静态库。
静态库文件名的命名规范是以lib为前缀,紧接着跟静态库名,扩展名为.a
例如:我们将创建的静态库名为hello,则静态库文件名就是libhello.a
执行:ar -crv libhello.a hello.o
生成libhello.a文件
(3)执行:gcc main.c -o hello_Hualai -L. -lhello
注意:
-L. (要加点!) 是指在当前路径下查找静态库
-lhello是指链接libhello.a,gcc会在静态库名前加上前缀lib,然后追加扩展名.a得到的静态库文件名来查找静态库文件
(4)使用ldd hello_Hualai
查看文件依赖库
(5)发现不会显示静态库的链接
动态库
(1)将.c文件编译为.so文件
执行:gcc -shared -fPIC hello.c -o libhello.so
生成libhello.so文件
-fPIC 创建与地址无关的编译程序(pic,position independent code),是为了能够在多个应用程序间共享
-shared是生成动态库的链接器选项
(2)将动态库移入系统库文件夹中,执行:sudo cp libhello.so /usr/lib/
如需指定路径,可声明环境变量,export LD_LIBRARY_PATH=
(3)编译链接动态库的可执行文件
执行:gcc main.c -o hello_Hualai -lhello
(4)使用ldd hello_Hualai
查看文件依赖动态库,可以找到libhello.so的链接
例程2
hello.c
#include <hello.h>//直接调用hello.h里的stdio.h
void say_hello()
{
printf("vw50\n");
}
int h=114514;
hello.h 学习写法!
#include<stdio.h>
void say_hello();
extern int h;//声明全局变量
main.c
#include<hello.h>
int main()
{
say_hello();
printf("%d\n",h);
return 0;
}
编译成动态库
$ gcc -fPIC -shared hell.c -I ./ -o libhell.so
编译成静态库
$ gcc -c hell.c -I ./
$ ar -rc libhell.a hell.o
然后目录中就会出现两个库文件
编译链接动态库
$ gcc main.c -I ./ -L . -lhell -o main1
编译链接静态库
$ gcc main.c -lhell -I . -L . -static -o main2
运行程序
./main1
./main2
正常情况,main1无法运行,是因为系统找不到库文件
临时添加库文件环境变量$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${PWD}
之后成功运行
使用ldd命令查看程序所调用的动态库
可以看到main1链接了hello动态链接库(其他链接的库是标准库)
main2则没有任何链接动态库
运用cmake文件
传统cmake文件
※注意库文件和实际执行的文件的install方式是不同的!
CMakeList.txt
写法
# 全局包含库文件
include_directories(${PROJECT_SOURCE_DIR}/include)
# 添加共享库
add_library(vw50 SHARED src/libHelloSLAM.cpp)
# 添加可执行文件
add_executable(useHello src/useHello.cpp)
# 设置可执行文件的公共头文件搜索路径
# 链接可执行文件和库
target_link_libraries(useHello vw50)
ament_target_dependencies(useHello ${dependencies})
# 安装库文件
install(TARGETS
vw50
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin
)
# 安装源文件
install(TARGETS
useHello
RUNTIME DESTINATION lib/${PROJECT_NAME}
)
ament构建文件
# 使其他包可以通过find_package找到
ament_export_targets(${PROJECT_NAME} HAS_LIBRARY_TARGET)