C++项目实践学习笔记---DLL

linux守护进程

  • 守护进程或精灵进程(Daemon):以后台服务方式运行的进程,它们不占用终端(Shell),因此不会受终端输入或其他信号(如中断信号)的干扰
  • 守护进程有如下特点。
    (1)守护进程没有控制终端,不能直接和用户交互,不会接收终端输入或信号,也不能向终端输出信息。
    (2)其他进程都是在用户登录或者运行程序时创建,在运行结束或用户注销时终止,但守护进程不受用户登录、注销的影响,它只受开机、关机的影响。
  • 守护进程和后台进程的区别如下。
    (1)守护进程是后台进程,但后台进程不一定是守护进程。
    (2)守护进程运行时与终端无关,不能向终端输出消息,因此不会受终端影响,即使关闭终端或用户注销(退出操作系统登录状态),守护进程也会继续运行;
    后台进程并未脱离终端,后台进程可以向终端输出信息并可接收来自终端的信号(如中断信号),关闭终端会导致该终端中运行的后台进程退出,用户注销也会导致后台进程退出。
    (3)守护进程的所属会话、当前目录、文件描述符都是独立的;后台进程只是终端进行了一次fork()函数,让程序在后台执行,因此后台进程的当前目录、文件描述符等都依赖所在终端。
  • 如何让一个进程变成守护进程
    1)创建子进程,终止父进程
    fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,
    一个进程调用fork()函数后,系统先给新的进程分配资源(如存储数据和代码的空间),
    然后把原来进程的所有值都复制到新进程中,只有少数值与原进程的值不同,这相当于克隆了一个进程。
    新旧两个进程可以做完全相同的事,也可以做不同的事,这可以由初始参数决定.
    fork()函数只会把下一个要执行的代码以及之后的代码复制到新进程
    fork()函数可能有以下三种不同的返回值。
    在父进程中,调用fork()函数成功,并且新创建子进程的进程ID>0。此时输出的信息见标号③处。
    在子进程中,fork()函数返回0。此时输出的信息见标号④处。
    如果出现错误,则fork()函数返回一个负值。此时可以通过errno的值判断错误原因。
    通过fork()函数返回的值来判断当前进程是子进程还是父进程
    在这里插入图片描述
    2)在子进程中创建新会话
    setsid()函数用于创建一个新的会话,并将调用它的进程设置为该会话组的组长
    setsid()函数有三个作用:让进程脱离原会话、让进程脱离原进程组、让进程脱离原终端
    调用setsid()函数的进程不能是进程组组长,父进程不能调用setsid()函数,即使调用也会失败
    需要先调用fork()函数创建子进程,这样的话父进程仍是会话组长、进程组长,而子进程不是。
    当子进程调用完setsid()函数之后,子进程是新会话的会话组长,也是新的进程组组长,并且脱离了控制终端
    //创建守护进程(后台进程)的函数
    #include<unistd.h>
    pid_t setsid(void);
    在这里插入图片描述
    3)关闭文件描述符
    通过fork()函数方式创建的子进程会从父进程那里继承一些已经打开的文件句柄。子进程可能永远不会操作这些被打开的文件,但它们却会消耗系统资源,而且可能导致文件所在的文件系统(如U盘、光盘)无法卸载。为了避免这种情况,需要关闭文件描述符,见代码清单2-16中标号①处。当关闭文件描述符之后再调用printf()之类接口时可能导致异常,这是因为printf()接口默认对终端进行操作,而此时进程已经同终端脱离了。因此应该把标准输入stdin、标准输出stdout、标准错误输出stderr进行重定向,见标号②处。
    在这里插入图片描述
    4)改变工作目录
    通过fork()创建的子进程也会继承父进程的当前工作目录。如果进程运行过程中一直占用该目录,将导致当前目录所在的文件系统不能卸载,因此,应该把当前工作目录换成其他的路径,如“/”。
    chdir(“/”);//更改目录防止占用可卸载的文件系统
    5)重设文件创建掩码
    通过fork()方式创建的子进程会从父进程那里继承文件创建掩码。文件创建掩码指的是屏蔽掉文件创建时对应的访问权限位。文件的访问权限共有9种,分别是用户读、用户写、用户执行、组读、组写、组执行、其他读、其他写、其他执行。可以通过umask()设置文件创建掩码,其实这个函数的作用就是为当前进程设置创建文件或者目录的最大可操作权限。比如,umask(0)的含义是0取反再与创建文件时的权限相与。如果用mode代表文件创建权限,那么umask(0)的含义是(~0)&mode,也就是八进制的777&mode。这样的话,在此之后的代码在创建文件或目录时就可以给出最大的权限,避免了创建目录或文件时权限的不确定性。
    umask(0);// 重设文件创建掩码

在Windows系统中以后台服务方式运行程序

  • 1.注册/注销服务
    引入Advapi32.lib库,
    在这里插入图片描述

2.启动服务
start_service()的实现如下。该接口通过调用“::StartServiceCtrlDispatcher()”实现了服务的启动。
在这里插入图片描述
3.在进程中增加对注册、注销、启动服务接口的调用代码
完成服务的注册、注销、启动接口后,就可以在应用进程中调用这些接口了。

  • 将DLL中供EXE调用的类或接口称作引出类、引出接口。
    (1)将DLL中引出类(export)的头文件移动到公共include目录。
    (2)在DLL的pro项目文件中定义宏。
    (3)编写DLL引出宏的头文件。
    (4)在DLL引出类的头文件中使用引出宏。
    (5)在EXE项目中添加对DLL的引用。
    (6)在EXE中调用DLL的接口。
    (7)使用命名空间解决重名问题。
    (8)使用命名空间的注意事项。

在这里插入图片描述
在Windows中,WINAPI被定义为_ _stdcall

  • 动态加载的DLL和静态链接的DLL有什么区别:
    (1)构建过程中对DLL的lib文件的依赖不同。如果使用静态链接的DLL,在构建EXE项目时需要用到DLL的lib文件,以便链接DLL中的符号,如引出类、引出接口;如果使用动态加载的DLL,在构建EXE项目时不需要DLL的lib文件。
    (2)在运行过程中,对DLL的依赖时间不同。如果使用静态链接的DLL,EXE整个运行过程中都要依赖DLL库文件(如a.dll);如果使用动态加载的DLL,EXE只有在加载该DLL后才依赖DLL库文件,而在卸载DLL后就不再依赖DLL库文件了,这时即使删除该DLL库文件也不影响EXE的正常运行。

  • 开发动态加载的DLL分为两步,第一步是开发可动态加载的DLL,第二步是动态加载DLL

  • extern "C"是让C++代码能够调用C代码写的接口而采用的一种语法形式

  • Windows动态加载DLL步骤:

  • 加载DLL: HMODULE WINAPI LoadLibrary(In LPCTSTR lpFileName);
    _In_表示后面的参数是输入参数,也就是在接口内部只会引用传入的参数,而不会修改它。
    参数lpFileName表示要加载的DLL名称,如果DLL所在路径已经配置到PATH环境变量,就可以不写全路径而只写DLL文件名
    HMODULE是返回值类型,它是一个句柄,用来操作打开的DLL
    HMODULE hDll = LoadLibrary(“my_dll.dll”);

  • 查找DLL中的接口:
    WINBASEAPI FARPROC WINAPI GetProcAddress(In HMODULE hModule, In LPCSTR
    lpProcName);
    WINBASEAPI宏用来表明后面是一个引出接口。
    FARPROC表示该接口的返回值类型是一个函数地址,也就是DLL中接口的地址。
    hModule是指向DLL的句柄,hModule可以取LoadLibrary()的返回值。
    lpProcName表示要查找的接口名
    void *pFuncAddress = GetProcAddress(hDll, “function_test”);

  • 调用DLL中的接口、

  • 在这里插入图片描述

  • 卸载DLL
    WINBASEAPI BOOL WINAPI FreeLibrary(In_ HMODULE hLibModule)
    hLibModule表示DLL的句柄,该句柄可以由LoadLibrary()得到。
    FreeLibrary()返回BOOL类型的值,用来表示卸载成功与否
    FreeLibrary(hDll);

  • 在Linux中动态加载DLL并调用DLL中的接口步骤

  • (1)如果要调用DLL中的接口,首先需要加载DLL。在Linux中加载DLL的接口为dlopen(),调用该接口需要包含头文件“#include <dlfcn.h>”, - void* dlopen(const char pathName, int mode);
    其中pathName表示要加载的DLL名称,如果DLL所在路径已经配置到PATH环境变量,就可以不写全路径而只写DLL文件名。
    mode 表示加载模式,在本案例中取值RTLD_LAZY,表示等需要时再解析DLL中的符号(即函数)。
    该函数返回值类型为void
    。调用dlopen()的示例代码如下。
    void *hDll = dlopen(“my_dll.so.1”, RTLD_LAZY);
    该例子表示加载的DLL为"my_dll.so.1"。需要注意的是Linux中的DLL文件一般会有多个软链接(类似Windows中的快捷方式),在使用前需要确认该文件名与磁盘上DLL的实际文件名是否一致,如果不一致将导致加载失败

  • (2)在Linux系统中加载DLL后,可以用dlsym()查找DLL中的接口, void* dlsym(void *handle, const char symbol);
    void
    指向返回的函数地址。
    handle是指向DLL的指针,可以取dlopen()的返回值。
    symbol表示要查找的接口名。
    调用dlsym()的示例代码如下。
    void *pFuncAddress = dlsym(hDll, “function_test”);
    该示例表示在hDll所指向的DLL中查找函数function_test并将找到的函数地址保存到pFuncAddress中。

  • (3)找到DLL中的接口后,就可以调用它了。

  • (4)完成接口调用后,如果不需要再调用该DLL中的接口,可以在适当的时机卸载DLL。但是,如果仍然需要调用其中的接口,就不能卸载DLL,否则将导致接口调用异常。在Linux中卸载DLL的接口为dlclose(), int dlclose (void *handle);
    其中handle表示DLL的句柄,该句柄可以由dlopen()得到。只有当DLL的使用计数为0时,DLL才会真正被系统卸载。 dlclose(hDll);
    注意:如果要使用dlopen()、dlclose()等接口,需要在项目的pro中添加对Linux库dl的引用,否则会导致编译错误“undefined reference to symbol ‘dlclose@@GLIBC_2.2.5’”

将动态加载DLL的功能封装到自定义类

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

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

相关文章

高性能并行计算课程论文:并行网络爬虫的设计与实现

目录 1.绪论 1.1 研究背景 1.2 研究意义 ​​​​​​​1.3 文章结构 2. 网络爬虫相关理论 ​​​​​​​2.1 URL地址格式 ​​​​​​​2.2 网页爬取策略 2.2.1 深度优先策略 2.2.2 广度优先策略 2.2.3 最佳优先策略 ​​​​​​​2.3 网页分析算法 ​​​​​​​2.3.1 正…

微软发布Phi-3系列语言模型:手机端的强大AI助手

大模型&#xff08;LLMs&#xff09;在处理复杂任务时展现出的巨大潜力&#xff0c;但却需要庞大的计算资源和存储空间&#xff0c;限制了它们在移动设备等资源受限环境中的应用。微软公司最新发布的Phi-3系列语言模型&#xff0c;以其卓越的性能和小巧的体积&#xff0c;打破了…

c++习题01-ljc的暑期兼职

目录 一&#xff0c;题目描述 二&#xff0c;思路 三&#xff0c;伪代码 四&#xff0c;流程图 五&#xff0c;代码 一&#xff0c;题目描述 二&#xff0c;思路 1&#xff0c;根据题目要求需要声明4个变量&#xff1a;a,b,c,d ;牛奶价格a&#xff0c;活动要求b&…

柯桥商务英语培训under是“在下面”,dog是“狗”,那underdog是什么意思?

英语中有很多单词 拆开看都认识 但合在一起意思就变了 就比如这个表达&#xff1a;underdog 大家都知道&#xff1a;under是下面&#xff0c;dog是狗 那么underdog是啥意思呢&#xff1f; 在小狗下面&#xff1f; 还是活得连狗都不如&#xff1f; 当然没有那么简单 但我…

flask 接收vuejs element el-upload传来的多个文件

el-upload通过action指定后端接口,并通过name指定传输的文件包裹在什么变量名中 <el-uploadclass="upload-demo"dragaction="https://ai.zscampus.com/toy/upload"multiplename="fileList":limit="10"accept=

Linux-笔记 使用SCP命令传输文件报错 :IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!

前言 使用scp命令向开发板传输文件发生报错&#xff0c;报错见下图; 解决 rm -rf /home/<用户名>/.ssh/known_hosts 此方法同样适用于使用ssh命令连接开发板报错的情况。 参考 https://blog.csdn.net/westsource/article/details/6636096

【Java Web】Axios实现前后端数据异步交互

目录 一、Promise概述 二、Promise基本用法 三、async和await关键字 四、Axios介绍 4.1 Axios基本用法 4.2 Axios简化用法之get和post方法 五、Axios拦截器 六、跨域问题处理 一、Promise概述 axios是代替原生的ajax实现前后端数据交互的一套新解决方案&#xff0c;而axios使用…

Geotools系列说明之入门介绍与坐标系转换说明

Geotools介绍 借用官网的介绍 GeoTools is an open source Java library that provides tools for geospatial data 就是提供java处理地理空间的工具详细内容请参考官网 Geotools环境搭建 我们这里只讨论Geotools在Maven中和Idea的项目实战&#xff0c;至于Geotools的服务端…

Filter and Search

应用筛选器时&#xff0c;“视图”仅显示符合当前筛选条件的记录。您可以根据一列或多列筛选数据。如果针对多个列进行筛选&#xff0c;则网格会在列筛选器之间应用AND逻辑运算符。 GridControl-Grid View 大多数DevExpress数据感知组件&#xff08;数据网格、树列表、垂直网…

讯飞星火企业智能体平台正式发布,打造每个岗位专属AI助手

大力财经 | 发布 讯飞星火V4.0来了&#xff01;6月27日&#xff0c;科大讯飞在北京发布讯飞星火大模型V4.0及相关落地应用。讯飞星火V4.0七大核心能力全面提升&#xff0c;整体超越GPT-4 Turbo&#xff0c;在8个国际主流测试集中排名第一&#xff0c;国内大模型全面领先。 大模…

台灯的功能作用有哪些?分享好用的护眼灯!看完就知道台灯怎么选

在当今时代&#xff0c;学生们长时间地沉浸于平板、手机、电脑等电子设备中&#xff0c;这些设备的屏幕往往伴随着频闪和蓝光辐射&#xff0c;这无疑对视力健康构成了潜在威胁。家长们日益关注孩子的护眼养眼问题&#xff0c;因为视力疲劳和眼部疾病不仅会降低个体的生活质量&a…

已解决:macOS Navicat保存密码失败(Failed to save password Error code: -34018),错误代码34018

Navicat 16 包括 Navicat15诸多版本都存在着问题&#xff0c;还要我去搞什么钥匙串访问&#xff0c;真麻烦&#xff01; Failed to save password Error code: -34018别搞那些有的没的方案&#xff01;就是TNT没 PJ 完美才导致这个问题出现&#xff0c;现在换了个PJ好的16.3.7版…

哈希表 | 哈希查找 | 哈希函数 | 数据结构 | 大话数据结构 | Java

&#x1f64b;大家好&#xff01;我是毛毛张! &#x1f308;个人首页&#xff1a; 神马都会亿点点的毛毛张 &#x1f4cc;毛毛张今天分享的内容&#x1f586;是数据结构中的哈希表&#xff0c;毛毛张主要是依据《大话数据结构&#x1f4d6;》的内容来进行整理&#xff0c;不…

上午写的博客,下午就上了bing首页,惊不惊喜,意不意外

今天上午写了一篇《用免费的“山水博客”来管理你的离线文章》的博客&#xff0c;没想到下午在必应就搜到了&#xff0c;而且还是首页第四个。 不由的让人感概&#xff0c;以前写了那么多的博客&#xff0c;想将排名排前点&#xff0c;在网上找了不少秘籍&#xff0c;都没成功&…

神经网络学习笔记9-简单的反向传播和线性回归

tensor在pytorch中是一个非常重要的类型 假如需要计算梯度&#xff0c;就将tensor中 requires_grad设为true loss是一个张量&#xff0c;在做运算时构建运算图&#xff0c;因此不要直接进行&#xff0c;会将将梯度存入w&#xff0c;当反向传播完成 后&#xff0c;该计算图会…

计算机的错误计算(十四)

摘要 解读 GPU和CPU计算上的精度差异&#xff1a;GPU 的 3个输出的相对误差分别高达 62.5%、50%、62.5%。 例1. 计算下列两个矩阵的乘积&#xff1a; 显然&#xff0c;其结果为第一列&#xff1a; 这个结果是准确的。 例2. 已知上面 3 个矩阵是由下面代码产生或输出&…

奔驰汽车的通信如此固若金汤的原因

随着摄像系统、距离控制、航线保持等功能以及制动辅助系统、制动力分配系统、车身侧倾干预与缓解系统等功能的飞速发展,汽车的系统功能之间已经不再独立,而是呈现互相合作的关系,各功能之间的无缝集成更是各大整车厂追求的目标。俗话说,外练筋骨皮,内练一口气,有了各式安…

HexPlane代码复现(十几分钟就复现成功的一篇论文代码!!!!!)

https://caoang327.github.io/HexPlane/ 一、 python setup.py develop命令用不了了 running develop /home/uriky/anaconda3/envs/hexplane/lib/python3.8/site-packages/setuptools/command/easy_install.py:144: EasyInstallDeprecationWarning: easy_install command is d…

ISO 50001能源管理体系:激活绿色动能和共塑可持续发展

在当今全球化加速和工业化水平不断提高的背景下&#xff0c;能源消费呈现出前所未有的增长趋势。然而&#xff0c;能源资源的有限性、能源价格的波动以及能源消费对环境造成的影响&#xff0c;尤其是温室气体排放导致的全球气候变化问题&#xff0c;已经成为全球关注的焦点。为…

怎么在必应bing上投放搜索广告?

搜索引擎已成为企业获取潜在客户、提升品牌曝光度的关键平台&#xff0c;微软必应&#xff08;Bing&#xff09;以其庞大的用户基数、精准的定位能力以及与微软生态系统的深度整合&#xff0c;为企业提供了极具价值的广告投放渠道。云衔科技助力企业实现必应bing广告的精准投放…