Linux下C++动态链接库的生成以及使用

目录

  • 一.前言
  • 二.生成动态链接库
  • 三.使用动态链接库


一.前言

这篇文章简单讨论一下Linux下如何使用gcc/g++生成和使用C++动态链接库(.so文件)。

二.生成动态链接库

先看下目录结构

在这里插入图片描述

然后看下代码

//demo.h

#ifndef DEMO_H
#define DEMO_H

#include<string>

class Demo
{
public:
	Demo(void) = default;
	~Demo(void) noexcept = default;
	void Print(const std::string& msg);
};

#endif // !DEMO_H
//demo.cpp

#include"demo.h"

#include<iostream>

void Demo::Print(const std::string& msg)
{
	std::cout << "msg:" << msg << std::endl;
}

很简单的代码,就是提供一个打印字符串的接口。

然后我们使用demo.h和demo.cpp来生成动态链接库。

执行命令g++ -shared -fPIC demo.cpp -o libdemo.so生成动态链接库libdemo.so,注意动态链接库必须要包含lib前缀,另外我们知道Linux下动态链接库的后缀是.so。

g++ -shared -fPIC demo.cpp -o libdemo.so命令中:
-shared表示生成动态链接库
-fPIC表示生成位置无关的代码,有些系统需要无论加载到什么位置都可以正常工作的位置无关代码

在这里插入图片描述

我们可以看到已经生成了动态链接库libdemo.so。

三.使用动态链接库

我们看一下怎么使用动态链接库,新建main.cpp来使用动态链接库。

先看下目录结构

在这里插入图片描述

然后看下代码

//main.cpp

#include<string>

#include"demo.h"

int main(int argc, char* argv[])
{
	Demo demo;
	std::string strMsg("main msg");

	demo.Print(strMsg);

	return 0;
}

其实就是很简单的代码。

然后执行命令g++ -o main main.cpp -L. -ldemo使用main.cpp和libdemo.so生成可执行文件main。其中-L.指定要链接的库所在位置是当前目录,-ldemo指定要链接的库是libdemo.so。

在这里插入图片描述

我们可以看到已经生成了可执行文件main,我们试着执行一下。

在这里插入图片描述

发现报错,这个错误信息就是找不到动态链接库libdemo.so,我们使用ldd ./main命令确认一下情况。

在这里插入图片描述

我们发现确实找不到动态链接库libdemo.so,这是因为系统不知道去哪里找libdemo.so,具体内容这篇文章里就不展开了,我们先使用命令export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/debian/code/demo设置环境变量解决一下,这个目录是libdemo.so所在的位置。

在这里插入图片描述

我们可以看到这个时候就可以找到动态链接库libdemo.so了,而且可以正常执行。这个时候如果删除了动态链接库libdemo.so,main也会不可以正常执行了,这是动态链接库的特性,也就是所谓的动态链接。

需要注意的是,动态链接库的符号其实是需要导出的,g++编译的时候默认是设置-fvisibility=default选项,默认就会导出符号,但是如果开启了-fvisibility=hidden选项,我们想要导出某个符号的话,就需要设置属性__attribute__((visibility(“default”)))。

比如我们使用命令g++ -shared -fPIC ./demo.cpp -o libdemo.so -fvisibility=hidden来生成动态库libdemo.so,那这个时候执行main就会报错的。

在这里插入图片描述

这个报错的意思就是符号未定义。

我们修改一下声明代码就可以解决了。

看下代码

//demo.h

#ifndef DEMO_H
#define DEMO_H

#include<string>

class Demo
{
public:
	Demo(void) = default;
	~Demo(void) noexcept = default;
	__attribute__((visibility("default"))) void Print(const std::string& msg);
};

#endif // !DEMO_H

然后我们还是使用命令g++ -shared -fPIC ./demo.cpp -o libdemo.so -fvisibility=hidden来生成动态库libdemo.so。

在这里插入图片描述

这个时候main就可以正常执行了。

在这里插入图片描述


欢迎讨论,欢迎指正,欢迎转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/233407.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

键盘打字盲打练习系列之矫正坐姿——4

一.欢迎来到我的酒馆 盲打&#xff0c;矫正坐姿&#xff01; 目录 一.欢迎来到我的酒馆二.继续练习二.矫正坐姿1.键盘与鼠标2.椅子 三.改善坐姿建议 二.继续练习 前面的章节&#xff0c;我们重点向大家介绍了主键盘区指法和键盘键位。经过一个系列的教程学习&#xff0c;相信大…

C语言数据结构-双向链表

文章目录 1 双向链表的结构2 双向链表的实现2.1 定义双向链表的数据结构2.2 打印链表2.3 初始化链表2.4 销毁链表2.5 尾插,头插2.6 尾删,头删2.7 根据头次出现数据找下标2.8 定点前插入2.9 删除pos位置2.10 定点后插入 3 完整代码3.1 List.h3.2 Lish.c3.3 test.c 1 双向链表的结…

redis中缓存雪崩,缓存穿透,缓存击穿等

缓存雪崩 由于原有缓存失效&#xff08;或者数据未加载到缓存中&#xff09;&#xff0c;新缓存未到期间&#xff08;缓存正常从Redis中获取&#xff0c;如下图&#xff09;所有原本应该访问缓存的请求都去查询数据库了&#xff0c;而对数据库CPU和内存造成巨大压力&#xff0c…

数据结构算法-希尔排序算法

引言 在一个普通的下午&#xff0c;小明和小森决定一起玩“谁是老板”的扑克牌游戏。这次他们玩的可不仅仅是娱乐&#xff0c;更是要用扑克牌来决定谁是真正的“大老板”。 然而&#xff0c;小明的牌就像刚从乱麻中取出来的那样&#xff0c;毫无头绪。小森的牌也像是被小丑掷…

C++ 学习系列 -- 实现简单的 String

1 标准库 std::string c 中的 std::string 是一个重要的字符串的类, 我们在日常工作中常常与之打交道。 string是C标准库的重要部分&#xff0c;主要用于字符串处理。使用string库需要在同文件中包括该库 #include<string> std::string 实际上是 std::basic_string<…

基于ssm应急资源管理系统论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本应急资源管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息…

jupyter notebook设置代码提示(代码补全)

1.当你打开jupyter notebook时&#xff0c;写代码的时候是默认没有代码提示的。 在base环境依次输入以下四行命令&#xff1a; pip install jupyter_contrib_nbextensions jupyter contrib nbextension install --user pip install jupyter_nbextensions_configurator jupyter …

系统架构设计师教程(二)计算机系统基础知识

系统架构设计师 2.1 计算机系统概述2.2 计算机硬件2.2.1 计算机硬件组成2.2.2 处理器2.2.3 存储器2.2.4 总线2.2.5 接口2.2.6 外部设备 2.3 计算机软件2.3.1 计算机软件概述2.3.2 操作系统2.3.3 数据库关系数据库关系数据库设计的特点及方法关系数据库设计的基本步骤 分布式数据…

python3使用pandas备份mysql数据表

操作系统 &#xff1a;CentOS 7.6_x64 Python版本&#xff1a;3.9.12 MySQL版本&#xff1a;5.7.38 日常开发过程中&#xff0c;会遇到mysql数据表的备份需求&#xff0c;需要针对单独的数据表进行备份并定时清理数据。 今天记录下python3如何使用pandas进行mysql数据表的备…

ubuntu20 安装docker

一.官网安装文档 &#xff08;基本按官方文档安装&#xff09; Install Docker Engine on Ubuntu | Docker Docs 二.安装步骤 1.docker 需要64位操作系统、linux内核要在3.1以上 #uname -r 2.卸载可能存在的旧版本 #sudo apt-get remove docker docker-engine docker-ce …

整数分析 C语言xdoj43

问题描述 给出一个整数n&#xff08;0<n<100000000&#xff09;。求出该整数的位数&#xff0c;以及组成该整数的所有数字中的最大数字和最小数字。 输入说明 输入一个整数n&#xff08;0<n<100000000&#xff09; 输出说明 在一行上依次输出整数n的位…

【无标题】安装环境

这里写目录标题 清华镜像加速 安装cuda11.3 PyTorch 1.10.1https://pytorch.org/get-started/previous-versions/[如果没有可以点Previous pyTorch Versions&#xff0c;这里面有更多的更早的版本](https://pytorch.org/get-started/locally/) 复制非空文件夹cp: -r not specif…

Linux下通过find找文件---通过修改时间查找(-mtime)

通过man手册查找和-mtime选项相关的内容 man find | grep -A 3 mtime # 这里简单介绍了 -mtime &#xff0c;还有一个简单的示例-mtime n Files data was last modified n*24 hours ago. See the comments for -atime to understand how rounding affects the interpretati…

Linux——缓冲区与C库的实现原理

一.缓冲区 1缓冲区的概念 缓冲区的本质就是一段内存 2.缓冲区存在的意义 提高使用者的效率 同时因为缓冲区的存在也提高了操作系统的效率 举例一个例子&#xff1a; 假如你在云南要给你北京的朋友寄东西。方法一&#xff1a;你可以亲自己去北京把东西交给他&#xff0c;方…

28. 深度学习进阶 - LSTM

文章目录 Hi, 你好。我是茶桁。 我们上一节课&#xff0c;用了一个示例来展示了一下我们为什么要用RNN神经网络&#xff0c;它和全连接的神经网络具体有什么区别。 这节课&#xff0c;我们就着上一节课的内容继续往后讲&#xff0c;没看过上节课的&#xff0c;建议回头去好好…

深度学习 | 前馈神经网络与反向传播算法

目录 一、Logistic函数 二、前馈神经网络&#xff08;FNN&#xff09; 三、反向传播算法&#xff08;BP算法&#xff09; ​四、基于前馈神经网络的手写体数字识别 一、Logistic函数 Logistic函数是学习前馈神经网络的基础。所以在介绍前馈神经网络之前&#xff0c;我们首…

消息队列使用指南

介绍 消息队列是一种常用的应用程序间通信方法&#xff0c;可以用来在不同应用程序或组件之间传递数据或消息。消息队列就像一个缓冲区&#xff0c;接收来自发送方的消息&#xff0c;并存储在队列中&#xff0c;等待接收方从队列中取出并处理。 在分布式系统中&#xff0c;消…

对无向图进行邻接矩阵的转化,并且利用DFS(深度优先)和BFS(广度优先)算法进行遍历输出, 在邻接矩阵存储结构上,完成最小生成树的操作。

一 实验目的 1&#xff0e;掌握图的相关概念。 2&#xff0e;掌握用邻接矩阵和邻接表的方法描述图的存储结构。 3&#xff0e;掌握图的深度优先搜索和广度优先搜索遍历的方法及其计算机的实现。 4&#xff0e;理解最小生成树的有关算法 二 实验内容及要求 实验内容&#…

【Angular开发】Angular在2023年之前不是很好

做一个简单介绍&#xff0c;年近48 &#xff0c;有20多年IT工作经历&#xff0c;目前在一家500强做企业架构&#xff0e;因为工作需要&#xff0c;另外也因为兴趣涉猎比较广&#xff0c;为了自己学习建立了三个博客&#xff0c;分别是【全球IT瞭望】&#xff0c;【架构师酒馆】…

第 119 场 LeetCode 双周赛题解

A 找到两个数组中的公共元素 模拟 class Solution { public:vector<int> findIntersectionValues(vector<int> &nums1, vector<int> &nums2) {unordered_set<int> s1(nums1.begin(), nums1.end()), s2(nums2.begin(), nums2.end());vector<…