在C++程序中新建并使用库

创建一个新的cpp文件后,定义一个函数

我们希望这个函数是可以被多个程序调用的,而不是直接输入在程序中进行编译。在C++程序中,不是所有代码都会被编译成可执行文件,只有main函数所在的程序才可以生成可执行文件。而这个库是通过上一节中的配置文件CMakeLists.txt文件中,通过add_library命令调用的,命令格式如下:

cpp 复制代码
add_library(库名 文件名)

当使用add_library命令时,我们通过命令告诉CMake我们想要创建一个库。这个库可以是由一个或多个源文件编译而成的静态库或动态库。

例如,如果你有一个名为mylib的库,并且想要生成一个静态库(.a文件),你的CMakeLists.txt文件需要加入如下语句:

bash 复制代码
add_library(mylib lib.cpp)

这里,CMake将会编译lib.cpp文件并生成一个名为libmylib.a的静态库文件。

下面进行实操,如下图,我们把第一张图中的函数整体打包命名为一个叫Hello的库

随后进行编译

编译后我们发现生成了一个多余的libHello.a的文件,.a文件是一个静态库文件,它包含了编译后的函数和对象的二进制代码。这个文件对我们之前所写的函数进行了一个"打包",也就是我们得到的库,有了这个文件就可以调用我们之前所写的函数了,

然而,仅仅有.a文件是不够的,因为我们还需要知道库中包含哪些函数以及如何正确地调用它们。这就引入了头文件(.h文件)的概念。

头文件的作用是声明库中公开的函数和类的接口,它为开发者提供了必要的函数原型、类定义和其他相关的声明信息 。当你想要使用静态库中的某个函数时,你需要在源代码中包含对应的头文件,这样编译器就能够理解函数的签名(即函数的返回类型、名称和参数类型),并确保你在源代码中对函数的调用是正确的。

为了顺利调用函数,还需要一个Hello.h的头文件来告诉程序库里面有这样一个函数。

假设库中有一个函数void my_function(),头文件(mylib.h)大体格式如下:

cpp 复制代码
#ifndef MYLIB_H
#define MYLIB_H

void my_function();

#endif // MYLIB_H

或者(与上面的表达意思一致)

cpp 复制代码
#pragma once
void my_function();

同时,我们的CMakeLists.txt需要确保主程序链接到库:

bash 复制代码
add_executable(myapp main.cpp) 
target_link_libraries(myapp mylib)

这里,add_executable创建了一个名为myapp的可执行文件,target_link_libraries告诉CMake在链接时需要包含mylib库。

拓展:#pragma once 与 #ifndef 特性对比

特性 #pragma once #ifndef
标准性 非标准 标准
跨编译器 不一定支持 广泛支持
实现机制 编译器层面 预处理器
防止重复 单一编译单元 全局
宏冲突风险

这个头文件声明了my_function函数的存在,但没有定义它。函数的定义通常在库的源文件(如lib.cpp)中给出,在我们的操作中就是libHello.cpp(第一个图)。在修改完配置文件后,通过vim Hello.h创建一个文件,按上面的格式要求编辑头文件。

可以通过less命令查看并浏览文件内容,按q退出。至此,libHello.cpp和Hello.h构成了一个完整的库,可以进行调用,新建一个usehello.cpp文件并调用该头文件以及其包含的函数,程序如下。

然后需要创建可执行文件并确保CMakeLists.txt主程序链接到库

编译:

打开build文件夹后,文件如下,运行可执行文件,运行成功!

步骤总结:

1.新建一个.cpp文件并定义一个函数

创建一个源文件,例如mylib.cpp,并在其中定义一个函数。

2.在配置文件CMakeLists.txt中通过add_library命令创建一个库:

编辑CMakeLists.txt文件,使用add_library命令添加你的库,指定库的名称和源文件。

3.编译生成.a文件

运行CMake来配置项目,并生成构建系统,然后使用构建系统编译库,生成库文件(如.a.so)。

4.新建一个头文件.h

创建一个头文件,例如mylib.h,并在其中声明库中要公开的函数。

5.将CMakeLists.txt链接到库:

CMakeLists.txt中,使用target_link_libraries命令将你的可执行文件或库与新建的库链接起来。(假设你已经有一个可以利用该函数的cpp文件并在配置文件中配置完成)

6.编译并运行

再次运行CMake和构建系统,编译整个项目,包括使用了新库的文件。

运行生成的可执行文件,验证函数是否按预期工作。

相关推荐
程序员老邢17 分钟前
【技术底稿 32】Nginx 经典大坑复盘:本机公网域名自环代理,导致接口返回首页 / 404 实战排障
java·运维·nginx·前后端分离·技术底稿·后端部署
сокол30 分钟前
【网安-Web渗透测试-内网渗透】局域网ARP攻击与DNS劫持
服务器·网络·网络安全
忧云36 分钟前
开源 SSH 客户端 Netcatty:免费替代 Termius,带 AI 的现代化运维工具
运维·开源·ssh
想唱rap1 小时前
传输层协议TCP
linux·运维·服务器·网络·c++·tcp/ip
曦夜日长1 小时前
Linux系统篇,权限(二):缺省权限、最终权限的计算、文件隔离的两种方式
linux·运维·服务器
瑶池酒剑仙1 小时前
C++类和对象完全指南:从封装继承多态到内存布局的面向对象宝典(雨夜论道)
c语言·开发语言·c++·visual studio
云水一下2 小时前
黑客的“猜密码”游戏:SSH暴力破解实战与Linux安全加固
linux·渗透测试·ssh·暴力破解
kebidaixu2 小时前
OK3568开发板更新Ubuntu22.04方法总结
linux·运维·服务器
潇湘散客2 小时前
CAX软件插件化设计实现牛刀小试
c++·算法·图形学·opengl
Ricky_Theseus2 小时前
const 和 #define 的区别
c++