【编写库文件+使用库文件】

【编写库文件+使用库文件】

静态库

(1)拓展名.a(Linux) .lib(Windows) 编译时直接连接到可执行文件中

(2)静态库对函数库的链接是放在编译时期完成的

(3)程序在运行时与函数库再无瓜葛,移植方便

动态库

(1)拓展名.so+版本号 eg .so.8.0(Linux) .dll(Windows) 程序运行时动态链接

(2)把对一些库函数的链接载入推迟到程序运行的时期

(3)可以实现进程之间的资源共享 因此动态库也称为共享库

(4)将一些程序升级变得简单,甚至可以真正做到链接载入完全由程序员在程序代码中控制(显示调用)

编译过程

运用gcc指令

例程1

文件准备

hello.cpp

#include

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里的stdio.h

void say_hello()

{

printf("vw50\n");

}

int h=114514;

hello.h 学习写法!

#include

void say_hello();

extern int h;//声明全局变量

main.c

#include

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)