Linux下C编程使用动态链接库

为了方便程序功能的后期升级扩展,在程序设计时经常会用到动态库,这样子程序只有到运行阶段才会去加载动态库并且使用库中的函数,那么我们往往只需要更新DLL(Windows系统)或SO(Linux系统)文件即可达到,同时打包成库也有利于保密和核心技术的积累,话不多说,接下来看看Linux下的动态链接库相关内容:

1.头文件及编译选项 

在Linux下对so动态链接库进行操作时,需#include <dlfcn.h>,将dlfcn.h头文件包含进来,并且在使用gcc编译时要使用-ldl选项。 

2.常用函数 

a.void *dlopen(const char *filename, int flag); 

其中,函数返回动态库的操作Handle(句柄),filename为库名,而flag常用的值有如下两个(必须使用其中一个,其他标志可使用man dlopen查看): 
RTLD_LAZY:在打开SO时不对共享库的函数进行加载操作,等到dlsym调用时才加载指定函数; 
RTLD_NOW:在打开SO时将共享库的所有函数加载至内存。 

b.void *dlsym(void *handle, const char *symbol); 从dlopen返回的handle里找名为symbol的函数指针并将其返回,注意这里返回的是void *,须做类型转换。 

c.int dlclose(void *handle); 关闭dlopen打开的Handle。 

d.char *dlerror(void); 当上述动态链接库操作函数被调用后,再调用本函数时,返回NULL表示没有错误发生,如果有错误发现,其将返回一个错误字符串,即出错信息。 

3.如何查找库 这里忽略ELF文件里的DT_RPATH和DT_RUNPATH标志时的情况,下面是标准的查找库顺序:首先查找LD_LIBRARY_PATH环境变量对应的目录,找不到时再查找/etc/ld.so.cache文件(由ldconfig命令维护刷新),再找不到时则查找/lib和/usr/lib目录。 

4.如何制作SO 在gcc生成so时使用-shared参数。 

有了如上这些基础后,我们还是实例学习下如何使用so这玩意: 

slam.c(编译成slam.so):

#include <stdio.h>

void print(char *str)
{
        printf("%s\n", str);
}

cso_exam.c:

#include <stdio.h>
#include <dlfcn.h>

int main(int argc, char * argv[])
{
        if (argc != 2) {
                printf("Usage:%s whattoprint\n", argv[0]);
                return 0;
        }

        void * slam_handle;
        void (*print_func)(char * str);

        slam_handle = dlopen("slam.so", RTLD_LAZY);
        if (!slam_handle) {
                printf("dlopen failed.\n");
                return -1;
        }

        print_func = (void (*)(char*))dlsym(slam_handle, "print");
        if (dlerror() != NULL) {
                printf("dlsym failed.\n");
                return -1;
        }

        (*print_func)(argv[1]);

        return 0;
}

Makefile:

all:
        gcc -o slam.so -shared -fPIC slam.c
        gcc -rdynamic -o cso cso_exam.c -ldl

clean:
        rm -rf slam.so cso

对应的源码文件目录树如下: 

/home/xinu/xinu/c_cpp/c_so_example/ 
├── cso_exam.c 
├── Makefile 
└── slam.c 

至此,所有准备工作都搞定了,接下来make后会在当前目录下生成cso和slam.so两文件,为了让程序运行时搜索库能是当前目录,我们执行如下命令: 

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. 

接下来运行./cso hello就不会提示找不到库了。 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

tr,cut,diff(数据处理

tr 命令 功能&#xff1a; tr 命令用于转换或删除文件中的字符。 语法&#xff1a; 格式&#xff1a; tr [-cdst][--help][--version][第一字符集][第二字符集] tr [OPTION]…SET1[SET2] 标识符&#xff1a; -d&#xff1a;删除指定的字符。-s&#xff1a;压缩重复的字…

本地部署Xinference实现智能体推理工作流(二)

第二篇章 Dify接入 Xinference 部署的本地模型 1. 安装Dify 克隆 Dify 源代码至本地。 git clone https://github.com/langgenius/dify.git 2. 启动Dify 进入 Dify 源代码的 docker 目录&#xff0c;执行一键启动命令&#xff1a; cd dify/docker cp .env.example .env d…

【OWOD论文】开放世界中OD代码_2_模型部分

简介 本文记录OWOD代码中的模型代码部分。数据部分可看我上一个博客【【OWOD论文】开放世界中OD代码_1_数据部分-CSDN博客】 模型代码 1 起步 在代码中找到 detectron2\engine\defaults.py DefaultTrainer类 __init__方法 根据上述 build_model 回溯到 detectron2\modeling\…

无人机校企合作:组装、维修、研发全面提升学生技能方好就业

无人机校企合作在组装、维修、研发等方面全面提升学生技能&#xff0c;进而促进学生就业&#xff0c;是一个具有前瞻性和实践性的教育模式。以下是对该合作模式的详细分析&#xff1a; 一、合作背景与意义 随着无人机技术的快速发展和广泛应用&#xff0c;市场对无人机专业人…

Maya云渲染平台哪个好,5家云渲染整理

Maya云渲染服务可以帮助用户利用云计算技术&#xff0c;通过互联网访问专业的渲染农场&#xff0c;利用大规模的服务器实现云渲染&#xff0c;比如单镜头同时安排50-300台机器渲染&#xff0c;从而大幅提升渲染效率和便捷性。当然&#xff0c;市面上的渲染农场参差不齐&#xf…

叉车(工业车辆)安全管理系统,云端监管人车信息运营情况方案

近年来&#xff0c;国家和各地政府相继出台了多项政策法规&#xff0c;从政策层面推行叉车智慧监管&#xff0c;加大叉车安全监管力度。同时鼓励各地结合实际&#xff0c;积极探索智慧叉车建设&#xff0c;实现作业人员资格认证、车辆状态认证、安全操作提醒、行驶轨迹监控等&a…

react学习之useState和useEffect

useState useState 可以使函数组件像类组件一样拥有 state&#xff0c;函数组件通过 useState 可以让组件重新渲染&#xff0c;更新视图。 实际使用 setstate()中回调函数的返回值将会成为新的state值回调函数执行时&#xff0c; React会将最新的state值作为参数传递 const A…

Linux基础 -- 网络工具之curl使用

curl 使用手册 curl 是一个强大的命令行工具&#xff0c;用于与服务器进行HTTP请求。本文档将介绍常见的请求方法和一些高级用法。 基础用法 1. GET 请求 GET 请求用于从服务器获取数据。 curl -X GET "http://example.com/api/resource"2. POST 请求 POST 请求…

【HarmonyOS 4.0】@BuilderParam 装饰器

1. BuilderParam 装饰器 BuilderParam 装饰器用于装饰自定义组件(struct)中的属性&#xff0c;其装饰的属性可作为一个UI结构的占位符&#xff0c;待创建该组件时&#xff0c;可通过参数为其传入具体的内容。参数必须满足俩个条件&#xff1a; 2.1 参数类型必须是个函数&#x…

windows安全软件之火绒杀毒的密码忘记后处理

一、问题描述 某次&#xff0c;想升级系统补丁&#xff0c;但多次尝试后都失败&#xff0c;排查杀毒软件影响过程中&#xff0c;发现火绒杀毒配置了密码保护&#xff0c;但因时间太久&#xff0c;密码已无从考证&#xff0c;那我们应该怎样处理这种情况呢&#xff1f; 二、处…

鸿蒙XComponent组件的认识

概述&#xff1a; XComponent组件作为一种渲染组件&#xff0c;通常用于满足开发者较为复杂的自定义渲染需求&#xff0c;例如相机预览流的显示、游戏画面的渲染、自定义视频播放器等等。其中Native API是其核心内容&#xff01; 其可通过指定其type字段来实现不同的功能&…

jenkins安装k8s插件发布服务

1、安装k8s插件 登录 Jenkins&#xff0c;系统管理→ 插件管理 → 搜索 kubernetes&#xff0c;选择第二个 Kubernetes&#xff0c;点击 安装&#xff0c;安装完成后重启 Jenkins 。 2、对接k8s集群、申请k8s凭据 因为 Jenkins 服务器在 kubernetes 集群之外&#xff0c;所以…

解决huggingface下载时Username/Password Authentication Failed.问题

项目场景&#xff1a; 使用huggingface 下载数据集。 问题描述 运行命令&#xff1a; wget https://huggingface.co/datasets/yangtaointernship/RealEstate10K-subset/resolve/main/google_scanned_objects.zip?downloadtrue 完整报错如下&#xff1a; --2024-08-30 15:…

Windows通过网线连接开发板共享网络

Windows端 打开更开适配器选项右键WLAN–属性–共享 右键以太网–属性–Internet协议版本4(TCP/IPv4) 记住IP地址 开发板端 查看网卡 ifconfig设置IP在同一网段 ifconfig eth0 192.168.137.2 netmask 255.255.255.0设置网关 route add default gw 192.168.137.1配置DNS su…

哪个牌子的电容笔好用又实惠?西圣、绿联、摩米士电容笔实测大比拼

​现在市面上的电容笔很多&#xff0c;在选择时会让人感到很纠结。那么多的选择&#xff0c;究竟哪个牌子的电容笔好用又实惠呢&#xff1f;一款优质的电容笔应考虑握持舒适度、笔尖材质、电池续航能力以及书写流畅度等因素。作为一位多年的数码爱好者&#xff0c;我今天将针对…

Python中的列表:掌握数据操作的艺术

引言 列表是一种可变序列&#xff0c;它可以存储任意数量的不同类型的对象&#xff0c;并且支持添加、删除等操作。在实际开发中&#xff0c;列表被广泛应用于数据存储、临时计算结果保存、数据传输等多个场景。例如&#xff0c;在Web开发中&#xff0c;我们可以使用列表来存储…

atc 经典dp 26题 题型总结

题目链接 稍微记录下吧。主要想发现他 这个题单主人 是怎么去分类dp的类型的。借鉴 题目不一定要多难。但是题型的分类总结 感觉很重要。 某种dp的处理方式。。他是相似的。。 A B 数组 前面往i1 &#xff0c;i2.。。这样的推 。 C 限制只能 交叉继承。。不能继承pre一样位置的…

CSS3动画——飞行的小精灵

CSS3动画——飞行的小精灵 今天的这段代码通过多层结构、渐变色、圆角、多种动画效果以及细节处理&#xff0c;成功地创造了一个充满活力和趣味性的飞行小精灵动画效果。 效果如下&#xff1a; 飞行的小精灵 源代码如下&#xff1a; <!DOCTYPE html> <html lang&quo…

探索Edge-TTS与WebSocket集成:打造实时语音交互系统

本文为实现 WebSocket 将文本转换为语音并返回 Base64 数据给 Vue 客户端【干货】 在本文中&#xff0c;我们将构建一个简单的系统&#xff0c;该系统能够接收文本输入&#xff0c;通过 Microsoft Edge 的文本到语音服务&#xff08;Edge TTS&#xff09;转换为语音&#xff0c…

【第十三届蓝桥杯单片机国赛满分代码】

其他相关文章&#xff1a; 【提分必看&#xff01;】蓝桥杯单片机提分技巧&#xff08;国一经验分享&#xff09; 【国一超全代码分享&#xff01;】蓝桥杯单片机各模块代码整合 【蓝桥杯单片机客观题知识点汇总】 本代码经过编译后生成的hex文件经过了4T测试平台的满分测试。读…