首页 > 系统相关 >Linux下C++动态链接库的生成以及使用

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

时间:2024-07-31 18:53:37浏览次数:12  
标签:demo libdemo C++ cpp so Linux 动态链接库 main

目录

一.前言

这篇文章简单讨论一下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就会报错的(其实这个时候如果重新编译生成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就可以正常执行了。

在这里插入图片描述

标签:demo,libdemo,C++,cpp,so,Linux,动态链接库,main
From: https://blog.csdn.net/2401_85919417/article/details/140748130

相关文章

  • 【C++BFS算法 二分查找】2812. 找出最安全路径
    本文涉及知识点C++BFS算法C++二分查找LeetCode2812.找出最安全路径给你一个下标从0开始、大小为nxn的二维矩阵grid,其中(r,c)表示:如果grid[r][c]=1,则表示一个存在小偷的单元格如果grid[r][c]=0,则表示一个空单元格你最开始位于单元格(0,0)。在......
  • 【C++】构造函数的深入学习
    一、初始化列表C++提供初始化列表语法用来初始化属性语法:构造函数():属性1(值1),属性2(值2)...{}classPeople{public://传统初始化操作Person(inta,intb,intc){A=a;B=b;C=c;}//初始化列表初始化属性Pers......
  • 【C++】对象模型和this指针
    一、成员变量和成员函数分开存储只有非静态成员变量才属于类的对象上①C++编译器会给每一个空对象分配一个字节的空间,为了区分空对象占内存的位置classPerson{}voidtest(){PersonP;//空类(类中什么也没有)中的空对象所占内存空间为1cout<<sizeof(P......
  • linux文件系统
    一、文件系统相关知识Linux中一切皆文件,其中从根目录开始“/”往下呈现倒置的树桩结构。文件系统中有以下特点:1.区分大小写2.每个路径以/分割3.文件名最长255个字节4.蓝色-->目录绿色-->可执行文件红色-->压缩文件浅蓝色-->链接文件灰色-->其他文件5.以点开头的文件是隐......
  • Linux服务器设置jar包开机自启
    一、准备工作将jar包上传到服务器(本文将jar包上传到/home/project/jar/)新建脚本文件(本文将脚本文件放在/home/project/sh/文件下)注:sentinel-dashboard是我的程序名,可根据实际情况替换二、新建、编辑jar包的启动和停止脚本#启动脚本文件vim/home/project/sh/sentine......
  • C++面向对象编程解析
    文章目录1.概述2.作用解析3.概念解析1.类和对象2.封装(Encapsulation)3.继承(Inheritance)4.多态(Polymorphism)1.概述C++是在C语言的基础上增加了面向对象编程(OOP)特性的编程语言。面向对象编程是一种编程范式,通过将程序组织成对象的集合,这些对象包含数据和行......
  • Linux常见命令及帮助文档使用方法
    一、Linux中的常见命令查看系统信息1.查看CPU[root@Rocky8~]#lscpuArchitecture:x86_64CPUop-mode(s):32-bit,64-bitByteOrder:LittleEndianCPU(s):2...2.查看硬盘[root@Rocky8~]#lsblkNAMEMAJ:MINRMSIZE......
  • Linux 修改密码
    设置空密码Linux每次安装软件都要输入密码,对于个人使用来说这点很烦,因此我们可以在自用电脑上设置空密码。为帐户启用NOPASSWD选项删除帐户密码sudopasswd-d$(whoami)参考:CanIsetmyuseraccounttohavenopassword?|AskUbuntu强制修改密码可以通过切......
  • Linux中expect命令使用报错“invalid command name “Y“ while executing “Y“ invo
    1.执行expect命令的时候一直在报错:spawnshsetup.sh#invalidcommandname"Y"  whileexecuting"Y"  invokedfromwithin"expect"[Y]Yes,Iagree. [N]No,Idon'tagree."",如下图所示:其中的源码:    /usr/bin/expect&l......
  • Linux系统解压ZIP文件命令
    在Linux系统中,你可以使用unzip命令来解压ZIP文件。以下是一些基本的使用示例:解压ZIP文件到当前目录:bashunzipfilename.zip解压ZIP文件到指定目录:bashunzipfilename.zip-d/path/to/directory查看ZIP文件内容(不解压):bashunzip-lfilename.zip递归解压ZIP文件中的所有......