生成与调用C++动态链接库(so文件)
文章目录
- 前言
- 生成C++动态链接库
- 步骤1:编写C++源码
- 步骤2:生成共享库
- 步骤3:验证生成的SO文件
- 调用C++动态链接库
- 步骤1:修改原来makefile
- 步骤2:编译调用程序
- 步骤3:运行调用程序
- 总结
前言
动态链接库是代码重用和模块化的重要工具,它使得将功能封装为独立的库更加容易,同时还可以动态加载和升级这些库,提高了程序的灵活性和可维护性。
当我们希望将C++源码编译成动态链接库,并在其他应用程序中调用这个动态链接库,是这篇文章的应用场景。这篇文档将介绍如何创建、编译、链接和调用C++动态链接库。
PS:本文以下内容根据我实际工作项目编写,不采用demo的形式。
生成C++动态链接库
步骤1:编写C++源码
首先,编写C++源码文件,包括所需的类和函数。(看这篇文章的应该都有源码了吧!)
我实际的项目文件如下:

现在需要把ai_main.cpp编译成动态链接库。难点在于(完成后看来也不是什么难点):ai_main.cpp不仅调用了同级目录下的其他文件,还调用了其他路径的下源码文件(opencv等)
步骤2:生成共享库
使用C++编译器将源码编译成共享库,我这里采用的是aarch64-mix210-linux-g++编译工具链:
- 在同级目录下创建一个名为"
build"的文件夹,该文件夹将用于构建目标文件和.so文件。打开命令行终端并进入到该目录下。
mkdir build && cd build
- 运行以下命令,将所有依赖的
cpp文件编译为目标文件(.o文件):
aarch64-mix210-linux-g++ -c -fPIC -I/home/data/ai/opencv/include -I/home/data/ai/Ascend/ascend-toolkit/5.10.t20.0.b200/arm64-lmixlinux200/aarch64-linux/include ../*.cpp
-c选项告诉编译器只进行编译而不进行链接操作。
-fPIC选项表示生成位置无关代码,这是生成共享库所必需的。
-I选项指定头文件目录,如果有其他cpp文件中使用了头文件,则需要将其添加到该选项中。
- 运行以下命令将目标文件链接为共享库文件
.so:
aarch64-mix210-linux-g++ -shared -o libmy_main.so *.o
-shared选项表示生成共享库文件。
-o选项指定输出文件名。
完成后,你将在"build"文件夹中找到生成的libmy_main.so文件,这是可以给别人用来动态链接的共享库。

在上述命令中可以换成自己的编译工具(例如g++),需要根据实际情况修改文件名和路径。另外,如果代码中有其他库的依赖,你需要确保这些库已经安装并在编译/链接时正确配置了相关选项。
步骤3:验证生成的SO文件
通过运行以下命令来验证生成的SO文件是否可用:
file libmy_main.so
这应该显示类似于以下内容:
libmy_main.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked, not stripped
so文件生成成功。
检查符号链接:
运行以下命令,并确保输出中包含后续所需调用函数的定义。
nm libmy_main.so | grep ai_track
输出类似于:
0000000000061218 T ai_track
出现以上结果,说明ai_track函数在生成的共享库libmy_main.so中是可见的。这意味着该函数的定义在共享库中是存在的。ai_track需要替换成自己对外的接口函数,也就是其他程序调用so的函数。
调用C++动态链接库
现在,我们将展示如何在另一个C++程序中调用生成的C++动态链接库。我这是是做的测试,把原来源码编译部分替换成调用生成的so。
步骤1:修改原来makefile
# 注释掉原来调用原代码部分
# SMP_SRCSCPP += $(wildcard $(PWD)/../media/ai/src/*.cpp)
# 添加共享库的头文件和库路径
COMM_INC += -I/home/ai/src/build/include
CFLAGS += -L/home/src/build/lib# 添加共享库的链接标志,例如 libmy_main.so
CFLAGS += -lmy_main# 如果共享库是C++库,添加C++编译器标志
CFLAGS += -lstdc++
其中:
COMM_INC += -I/home/ai/src/build/include:目录下为so提供的函数接口的头文件,可以直接复用源码中对应的ai_main.h;
CFLAGS += -L/home/src/build/lib:确保 -L 选项中指定的共享库路径是正确的,并且包含了包含所需共享库libmy_main.so的目录;
CFLAGS += -lmy_main:通常,共享库名称应该是去掉 lib 前缀和 .so 后缀的部分。在这种情况下,libmy_main.so应该是 -lmy_main;
步骤2:编译调用程序
我这里直接在原来的基础上重新编译:
make clean && make -j4
运行完成后会生成可执行文件,我这里可执行文件暂为run_main
步骤3:运行调用程序
运行run_main文件时,需要指定so动态链接库的路径
export LD_LIBRARY_PATH=/path/to/your/library:$LD_LIBRARY_PATH
或者,可以在使用运行时链接:
run_main -rpath /path/to/your/library
这将在运行时为应用程序指定共享库的搜索路径。
无论您选择哪种方法,都确保共享库的路径设置正确,以便您的应用程序可以正确找到和加载所需的共享库。
总结
本文介绍了如何制作C++动态链接库(so文件)以及如何从另一个C++程序中加载和调用该库。本文主要从笔者自身项目出发,其中的过程不一定适用所有人。
如果阅读本文对你有用,欢迎一键三连呀!!!
2023年9月5日14:25:02

相关文章:
生成与调用C++动态链接库(so文件)
文章目录 前言生成C动态链接库步骤1:编写C源码步骤2:生成共享库步骤3:验证生成的SO文件 调用C动态链接库步骤1:修改原来makefile步骤2:编译调用程序步骤3:运行调用程序 总结 前言 动态链接库是代码重用和模…...
韶音的耳机怎么样,韶音骨传导耳机值得入手吗
韶音关于骨传导耳机的产品在质量方面还是有着不错的表现,其最具代表性的骨传导耳机就是韶音OpenRun Pro,在国产骨传导耳机中是具备了一定的知名度,有着自主研发的声学技术。 最突出的点就在于颜色上多样化,有着经典的黑色…...
STM32G030F6 (SOP-20)Cortex ® -M0+, 32KB Flash, 8KB RAM, 17 GPIOs
淘宝淘了一批 STM32G030F6P6 SOP20.先备注一下, 还没想到能干嘛用. 手上的 STM32F103C6T6还剩一些. 一堆 “淘宝原厂STM32F103C8T6”, 还烫着手. 理解信息: ( 逐步补充 ) System Clock GPIOs GPIOs 17 PA[7:0] : 8bits USART Timer ADC I2…...
常用的字符集和字符编码
基础概念 字符 字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等 字符集 一个操作系统支持的字符的集合。 字符编码和解码 将每个字符都设置一个唯一编号,编码就是将字符集中的字符编号以一定形式转化为字节存储下来,…...
容器技术简介
引言 随着云计算、大数据、人工智能等技术的不断发展,容器技术作为一种新兴的虚拟化技术,正逐渐成为IT领域的热点。容器技术可以帮助开发者更好地管理、部署和扩展应用程序,提高开发效率和应用程序的可靠性。本文将深入探讨容器技术的概念、…...
数据分享|R语言用lme4多层次(混合效应)广义线性模型(GLM),逻辑回归分析教育留级调查数据...
全文链接:http://tecdat.cn/?p22813 本教程为读者提供了使用频率学派的广义线性模型(GLM)的基本介绍。具体来说,本教程重点介绍逻辑回归在二元结果和计数/比例结果情况下的使用,以及模型评估的方法(点击文末“阅读原文…...
macos 不支持svn安装
macos 10.13可能不支持svn命令,所以要安装 xcode-select --install 弹窗在线安装失败的话只能手动下载安装 打开:Sign In - Apple 搜索Command Line Tools (macOS 10.13) 下载9.4.1版本直接安装后即可...
如何通过实际操作来加深对Linux命令和概念的理解?
作为一个新手,你一定不要被Linux那堆命令吓到。其实,它们就像你的“超能力”,只要你掌握它们,你就能成为Linux世界的超级英雄! 首先,我们要了解的是,Linux命令其实就像你的“魔法咒语”&#x…...
【开发语言】C语言与Python的互操作详解
博主未授权任何人或组织机构转载博主任何原创文章,感谢各位对原创的支持! 博主链接 本人就职于国际知名终端厂商,负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作,目前牵头6G算力网络技术标准研究。 博客…...
华为配置聚合vlan(Super vlan--Sub vlan)
聚合vlan,Aggregation vlan,也称Super vlan,可以实现用Sub vlan二层隔离广播域,但又将这些Sub vlan聚合使用同一IP子网和网关的情况。 这样,多个Sub-VLAN共享一个网关地址,节约了子网号、子网定向广播地址、…...
CentOS7安装时直接跳过了安装信息摘要页面的解决方法
最近在配置Hadoop虚拟机的时候,创建的centos7虚拟机在安装信息摘要时直接自动跳过,直接跳到设置用户名和密码,在重复多次的重新删除安装后发现了问题所在: 在进行到选择操作系统来源时,注意是否出现“该操作系统将使用…...
python基础运用例子
python基础运用例子 1、⼀⾏代码交换 a , b :a, b b, a2、⼀⾏代码反转列表 l[::-1]3、合并两个字典 res {**dict1, **dict2}**操作符合并两个字典for循环合并dict(a, **b) 的方式dict(a.items() b.items()) 的方式dict.update(other_dict) 的方式 4、⼀⾏代码列…...
k8s基本概念
一、什么是Kubernetes二:Kubernetes部署方式的演变三、为什么要用K8S四、K8S的特性五、Kubernetes 集群架构与组件5.1 Master 组件① Kube-apiserver② Kube-controller-manager③ Kube-scheduler④ AUTH 认证模块 5.2 配置存储中心5.3 Node 组件① Kubelet② Kube-…...
Python exp() 函数
描述 exp() 方法返回x的指数,ex。 语法 以下是 exp() 方法的语法: import mathmath.exp( x ) 注意:exp()是不能直接访问的,需要导入 math 模块,通过静态对象调用该方法。 参数 x -- 数值表达式。 返回值 返回x的指数,ex。 实例 以下展…...
Day 34 贪心算法 part03 : 1005.K次取反后最大化的数组和 134. 加油站 135. 分发糖果
134. 加油站 在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。 给定两个整数数组 gas…...
气象站的构成及功能应用
气象站是一种用于观测、记录和报告天气数据的设备。它是由数据采集系统、通讯系统、供电系统和立杆支架构成。 一、气象站的构成: 数据采集系统:用于测量气温、湿度、风速、风向、气压、降雨量、雪深等气象参数。 通讯系统:收集和处理传感…...
Qt中布局管理使用总结
目录 1. 五大布局 1.1 QVBoxLayout垂直布局 1.2 QHBoxLayout水平布局 1.3 QGridLayout网格布局 1.4 QFormLayout表单布局 1.5 QStackedLayout分组布局 1.6 五大布局综合应用 2. 分割窗口 3. 滚动区域 4. 停靠区域 1. 五大布局 1.1 QVBoxLayout垂直布局 #include <…...
(位运算) 剑指 Offer 15. 二进制中1的个数 ——【Leetcode每日一题】
❓ 剑指 Offer 15. 二进制中1的个数 难度:简单 编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为 汉明重量).)。 提示ÿ…...
基于SSM的新能源汽车在线租赁系统
末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用Vue技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#x…...
CTF 代码审计之绕过过滤的空白字符
题目 <?php header("Content-Type:text/html;charsetutf-8"); highlight_file(02kbzf.php);//引入名为 flag2.php 的文件。 include(f . lag2 . .php);//初始化变量 $info 和 $req。 $info ""; $req [];//读取文件 flag2.php 的内容到变…...
告别B站缓存碎片化:3步智能合并视频的终极解决方案
告别B站缓存碎片化:3步智能合并视频的终极解决方案 【免费下载链接】BilibiliCacheVideoMerge 项目地址: https://gitcode.com/gh_mirrors/bi/BilibiliCacheVideoMerge 你是否曾在高铁上打开B站缓存视频准备消遣时光,却发现播放器卡在开头几秒后…...
Zotero Better Notes终极指南:如何在笔记中创建流程图和思维导图
Zotero Better Notes终极指南:如何在笔记中创建流程图和思维导图 【免费下载链接】zotero-better-notes Everything about note management. All in Zotero. 项目地址: https://gitcode.com/gh_mirrors/zo/zotero-better-notes Zotero Better Notes是一款功能…...
千问图像生成16Bit(Qwen-Turbo-BF16)GPU利用率提升50%:BF16数值稳定性实证
千问图像生成16Bit(Qwen-Turbo-BF16)GPU利用率提升50%:BF16数值稳定性实证 基于 Qwen-Image-2512 底座与 Wuli-Art Turbo LoRA 构建的高性能、极速图像生成 Web 系统。 在AI图像生成领域,精度选择一直是性能与质量之间的关键权衡。…...
【无人机定位】无人机跳频信号 TDOA 定位仿真系统,信号生成(跳频、时延、衰减、噪声)、接收信号合成、时频分析、多算法定位【含Matlab源码 15278期】
💥💥💥💥💥💥💥💥💞💞💞💞💞💞💞💞💞Matlab武动乾坤博客之家💞…...
旧Mac焕新:使用OpenCore Legacy Patcher让2008-2017年设备支持最新macOS系统
旧Mac焕新:使用OpenCore Legacy Patcher让2008-2017年设备支持最新macOS系统 【免费下载链接】OpenCore-Legacy-Patcher Experience macOS just like before 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 老旧设备升级正成为越…...
IQuest-Coder-V1功能实测:一键生成高质量SQL查询脚本
IQuest-Coder-V1功能实测:一键生成高质量SQL查询脚本 在数据驱动的时代,SQL查询脚本的编写是每个数据分析师、后端工程师乃至产品经理的日常。面对复杂的业务逻辑和多表关联,手动编写SQL不仅耗时,还容易出错。有没有一种工具&…...
为什么高端芯片都爱用Flip Chip?对比Wire Bonding的5大优势详解
为什么高端芯片都爱用Flip Chip?对比Wire Bonding的5大优势详解 在芯片封装领域,Flip Chip(倒装芯片)技术正逐渐成为高端应用的标配。想象一下,当你手持最新款智能手机,流畅运行着复杂的AI应用时࿰…...
网络安全培训资源awesome-osint:OSINT视频教程与博客指南
网络安全培训资源awesome-osint:OSINT视频教程与博客指南 开源情报(OSINT)是网络安全领域的重要技能,通过公开可用的信息源收集情报。对于网络安全新手和从业者来说,找到高质量的OSINT培训资源至关重要。awesome-osin…...
ABAP开发必备:5种处理前导0的实战技巧(附SQL代码示例)
ABAP开发必备:5种处理前导0的实战技巧(附SQL代码示例) 在SAP ABAP开发中,物料号、供应商号等关键字段经常需要处理前导0的问题。这些看似简单的数字格式差异,却可能引发数据查询失败、报表统计错误等一系列"蝴蝶效…...
创建使用费曼学习技能,让 AI 帮你快速学习新领域知识(实战教程)
看完一篇文章、学习一个知识,当时感觉懂了。过三天,有人问你,你发现说不清楚。又或者准备运用这个知识,尝试解决问题,又觉得似是而非。这不是记忆力的问题,是你从来没有真正理解过它。有个方法专门解决这件…...
