当前位置: 首页 > news >正文

Linux中的算法分离手段

0. 简介

参数分离对于绝大多数算法开发来说收益是非常大的,因为我们都知道,随着平台的更替,很多时候如果说数据流和算法交叠在一起(即接口与实现合在一起)。这将有可能会导致在迁移平台时候会导致代码难以维护,并有可能会造成莫名的Bug。为了使代码更易于维护和扩展,在修改通信接口时不需要修改相关的算法代码,本文的下面将会介绍几种常用的方法。

1. 通过动态链接库完成链接

动态链接库(Dynamic Link Library,简称DLL)是一种在操作系统中用于共享代码和数据的机制。它是一种可执行的二进制文件,可以被多个程序同时使用,以提高代码的重用性和模块化程度。在C++算法分离中,动态链接库可以用于将算法代码从应用程序中分离出来,使得算法可以独立开发、测试和优化,同时也方便应用程序的调用和升级。

使用动态链接库可以使得算法代码和应用程序代码分别编译和链接,从而实现分离。这样一来,算法代码的修改和升级不会对应用程序造成影响,而应用程序也不必重新编译和链接。动态链接库还可以提高代码的重用性和可维护性,因为同一份动态链接库可以被多个应用程序使用,而且如果需要更新动态链接库,只需替换原文件即可。

对于动态链接库来说,主要分成两步。首先,需要在算法代码中明确定义导出函数(Export Function),以供应用程序调用。

比如说我们会创建一个函数my_pack_test.cpp

#include <stdio.h>
void foobar(int i)
{printf("Printing from my_pack_test.so %d\n", i);
}

CMakeList.txt

# include_directories( 这个括号里添加此项目依赖的头文件路径 )include_directories(../include)
add_library(my_pack_test 
# SHARED 字段指定testJni为动态链接库
SHARED 
# my_pack_test,为testJni库的cpp文件(生成testJni所需要的cpp都写到此处)
my_pack_test.cpp
)
# libgadl.so 为该testJni库需要链接的so库
target_link_libraries(testJni /home/lib/libgdal.so)
install(TARGETS my_pack_test LIBRARY DESTINATION lib)

这样我们就可以生成一个.so文件了。然后我们就需要在应用程序中使用动态链接库的导入函数(Import Function),以便在程序运行时动态加载动态链接库,并调用其中的算法函数。最后,需要将动态链接库文件放置在应用程序能够搜索到的路径下,以便程序能够找到它。

#include <iostream>
#include "mytool.h" // include the lib header// include shared lib load
#ifdef _WIN32
#include <windows.h>
#else
#include <dlfcn.h> # in linux, should also link to dl system library when build
#endif// define shared lib load handler
typedef MyTool *(*CreateMyToolFunc)();#ifdef _WIN32
HINSTANCE gDllHandler = nullptr;
const char *gDefaultSharedLibPath = "mytool.dll"; // here put it the same path
#else
void *gSoHandler = nullptr;
// 为上面生成的.so文件的绝对路径
const char *gDefaultSharedLibPath = "libmytool.so"; // here put it the same path, some linux must use ./libmytool.so
#endifint main()
{#ifdef _WIN32// load shared libgDllHandler = LoadLibrary(gDefaultSharedLibPath);if (!gDllHandler)std::cout << "load shared lib failed" << std::endl;CreateMyToolFunc create_mytool = (CreateMyToolFunc)(GetProcAddress(gDllHandler, "CreateMyTool"));MyTool *my_tool = create_mytool(); // get the derived class instance from shared libmy_tool->fun1();int z = my_tool->fun2(2, 3);printf("z: %d", z);// when all done, unload shared libFreeLibrary(gDllHandler);gDllHandler = nullptr;
#else// 加载指定的 .so 文件gSoHandler = dlopen(gDefaultSharedLibPath, RTLD_LAZY);if (!gSoHandler)std::cout << "load shared lib failed" << std::endl;CreateMyToolFunc create_mytool = (CreateMyToolFunc)(dlsym(gSoHandler, "CreateMyTool"));// 查找函数create_mytool,并返回函数指针MyTool *my_tool = create_mytool(); // get the derived class instance from shared lib// 调用对应的foobar函数打印输出my_tool->fun1();int z = my_tool->fun2(2, 3);printf("z: %d", z);// when all done, unload shared libdlclose(gSoHandler);gSoHandler = nullptr;
#endifreturn 0;
}

dlopen:该函数将打开一个新库,并把它装入内存。该函数主要用来加载库中的符号,这些符号在编译的时候是不知道的。这种机制使得在系统中添加或者删除一个模块时,都不需要重新进行编译。
dlsym:在打开的动态库中查找符号的值。
dlclose:关闭动态库。
dlerror:返回一个描述最后一次调用dlopen、dlsym,或dlclose的错误信息的字符串。

2. 通过进程完成链接

2.1 fork()完成子进程和父进程的操作

pid_t fork(void);

0: 子进程
子进程PID(大于0的整数):父进程
-1: 出错

使用fork函数得到的子进程从父进程的继承了整个进程的地址空间,包括:
进程上下文、进程堆栈、内存信息、打开的文件描述符、信号控制设置、进程优先级、进程组号、当前工作目录、根目录、资源限制、控制终端等。
子进程与父进程的区别在于:
1、父进程设置的锁,子进程不继承(因为如果是排它锁,被继承的话,矛盾了)
2、各自的进程ID和父进程ID不同
3、子进程的未决告警被清除;
4、子进程的未决信号集设置为空集

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int glob = 6;
int main()
{int local;int pid;local = 88; printf("parent[pid = %d]: before fork, glob(&glob) = %d(%p), local(&local) = %d(%p)\n",getpid(), glob, &glob, local, &local );if((pid = fork()) < 0) {perror("fail to fork");return -1; }   if(pid == 0) { /* child process */printf("child[pid = %d]: after fork, glob(&glob) = %d(%p), local(&local) = %d(%p)\n",getpid(), glob, &glob, local, &local );glob++;local++;    printf("child[pid = %d]: changed data after fork, glob(&glob) = %d(%p), local(&local) = %d(%p)\n",getpid(), glob, &glob, local, &local );}else { /* parent process */sleep(2);printf("parent[pid = %d]: after fork, glob(&glob) = %d(%p), local(&local) = %d(%p)\n",getpid(), glob, &glob, local, &local );}   /* return euqal to exit(0), but exit may cause a compile warning* due to main() is declared to return with an integter */return 0;  
}

在这里插入图片描述

2.2 exec函数族

…详情请参照古月居

相关文章:

Linux中的算法分离手段

0. 简介 参数分离对于绝大多数算法开发来说收益是非常大的&#xff0c;因为我们都知道&#xff0c;随着平台的更替&#xff0c;很多时候如果说数据流和算法交叠在一起&#xff08;即接口与实现合在一起&#xff09;。这将有可能会导致在迁移平台时候会导致代码难以维护&#x…...

机器学习实战:Python基于Logistic逻辑回归进行分类预测

目录1 前言1.1 Logistic回归的介绍1.2 Logistic回归的应用2 iris数据集数据处理2.1 导入函数2.2 导入数据2.3 简单数据查看3 可视化3.1 条形图/散点图3.2 箱线图3.3 三维散点图4 建模预测4.1 二分类预测4.2 多分类预测5 讨论1 前言 1.1 Logistic回归的介绍 逻辑回归&#xff…...

Leetcode.404 左叶子之和

题目链接 Leetcode.404 左叶子之和 easy 题目描述 给定二叉树的根节点 root&#xff0c;返回所有 左叶子 之和。 示例 1&#xff1a; 输入: root [3,9,20,null,null,15,7] 输出: 24 解释: 在这个二叉树中&#xff0c;有两个左叶子&#xff0c;分别是 9 和 15&#xff0c;所以…...

Android 11.0 原生SystemUI下拉通知栏UI背景设置为圆角背景的定制(二)

1.前言 在11.0的系统rom定制化开发中,在原生系统SystemUI下拉状态栏的下拉通知栏的背景默认是白色四角的背景, 由于在产品设计中,在对下拉通知栏通知的背景需要把四角背景默认改成圆角背景,所以就需要分析系统原生下拉通知栏的每条通知的默认背景, 然后通过systemui的通知…...

C语言CRC-16 IBM格式校验函数

C语言CRC-16 IBM格式校验函数 CRC-16校验产生2个字节长度的数据校验码&#xff0c;通过计算得到的校验码和获得的校验码比较&#xff0c;用于验证获得的数据的正确性。基本的CRC-16校验算法实现&#xff0c;参考&#xff1a; C语言标准CRC-16校验函数。 不同厂家通过对输入数…...

Maven高级-聚合和继承

Maven高级-聚合和继承3&#xff0c;聚合和继承3.1 聚合步骤1:创建一个空的maven项目步骤2:将项目的打包方式改为pom步骤3:pom.xml添加所要管理的项目步骤4:使用聚合统一管理项目3.2 继承步骤1:创建一个空的Maven项目并将其打包方式设置为pom步骤2:在子项目中设置其父工程步骤3:…...

如何写出10万+ Facebook 贴文?

想要创作一篇优秀的Facebook贴文&#xff0c;首先要考虑以下几个问题&#xff1a; 1.文案特点 一篇清晰简洁的文案有助于受众在有限的浏览时间内快速了解你想要展示的信息。根据以往经验&#xff0c;文案内容最好保持在20个汉字以内&#xff0c;加上链接描述最好也不要超过50…...

图像处理数据集

BSDS500 Berkeley Segmentation Dataset 500 是第一个用于评估超像素算法的数据集。对于参数优化&#xff0c;使用了验证集。 500张数据集200训练集train100验证集val200测试集test 每张图像有 5 个不同的高质量地面真值分割&#xff08;groundTruth,是.mat文件&#xff09; …...

文本聚类与摘要,让AI帮你做个总结

你好&#xff0c;我是徐文浩。 上一讲里&#xff0c;我们用上了最新的ChatGPT的API&#xff0c;注册好了HuggingFace的账号&#xff0c;也把我们的聊天机器人部署了出去。希望通过这个过程&#xff0c;你对实际的应用开发过程已经有了充足的体验。那么这一讲里&#xff0c;我们…...

leaflet实现波动的marker效果(131)

第131个 点击查看专栏目录 本示例的目的是介绍如何在vue+leaflet中显示波动的marker效果。 直接复制下面的 vue+leaflet源代码,操作2分钟即可运行实现效果. 文章目录 示例效果配置方式示例源代码(共76行)安装插件相关API参考:专栏目标示例效果 配置方式 1)查看基础设置…...

关于Dataset和DataLoader的概念

关于Dataset和DataLoader的概念 在机器学习中&#xff0c;Dataset和DataLoader是两个很重要的概念&#xff0c;它们通常用于训练和测试模型时的数据处理。 Dataset是指用于存储和管理数据的类。在深度学习中&#xff0c;通常将数据存储在Dataset中&#xff0c;并使用Dataset提…...

前端与JS变量

前端开发是当今互联网发展的重要组成部分&#xff0c;而JavaScript变量则是前端开发中不可或缺的一部分。在前端开发中&#xff0c;变量的作用不仅仅是存储数据&#xff0c;还可以用来控制程序流程、实现动态效果等。因此&#xff0c;学习前端与JavaScript变量是非常必要的。 …...

初始SpringBoot

初始SpringBoot1. SpringBoot创建和运行1.1. SpringBoot的概念1.2. SpringBoot的优点1.3. SpringBoot的创建1.3.0. 前置工作:安装插件(这是社区版需要做的工作, 专业版可以忽略)1.3.1. 社区版创建方式1.3.2. 专业版创建方式1.3.3. 网页版创建方式1.4. 项目目录介绍1.5. SpringB…...

vue+springboot 上传文件、图片、视频,回显到前端。

效果图 预览&#xff1a; 视频&#xff1a; 设计逻辑 数据库表 前端vue html <div class"right-pannel"><div class"data-box"><!--上传的作业--><div style"display: block" id""><div class"tit…...

java入门-W3(K81-K143)

一. 什么是对象 什么是对象&#xff1f;之前我们讲过&#xff0c;对象就是计算机中的虚拟物体。例如 System.out&#xff0c;System.in 等等。然而&#xff0c;要开发自己的应用程序&#xff0c;只有这些现成的对象还远远不够。需要我们自己来创建新的对象。 例如&#xff0c…...

English Learning - L2 语音作业打卡 复习元音 [ɜː] [æ] 辅元连读技巧 Day42 2023.4.3 周一

English Learning - L2 语音作业打卡 复习元音 [ɜː] [] 辅元连读技巧 Day42 2023.4.3 周一&#x1f48c;发音小贴士&#xff1a;&#x1f48c;当日目标音发音规则/技巧:中元音 [ɜː]前元音 []辅元连读技巧&#x1f36d; Part 1【热身练习】&#x1f36d; Part2【练习内容】&…...

Thinkphp 6.0图像处理功能

本节课我们来学习一下图像处理功能&#xff0c;这功能是外置的&#xff0c;并非系统内置。 一&#xff0e;图像处理功能 1. 图像处理功能不是系统内置的功能了&#xff0c;需要通过 composer 引入进来&#xff1b; composer require topthink/think-image 2. 引入进来之后&…...

表格软件界的卷王,Excel、access、foxpro全靠边,WPS:真荣幸

Excel和Access就是表格软件的选择&#xff1f; 现在&#xff0c;铺天盖地的Excel的技能教程可谓是满天飞&#xff0c;有网上的教程&#xff0c;也有视频直播课程。 很多办公人员用Excel这种表格软件与VBA结合&#xff0c;甚至用不遗余力去学习Python编程语法&#xff0c;但Exce…...

Node.js -- http模块

1. 什么是http模块 在网络节点中&#xff0c;负责消费资源的电脑&#xff0c;叫客户端&#xff1b;负责对外提供网络资源的电脑&#xff0c;叫做服务器。 http模块是Node.js官方提供的&#xff0c;用来创建web服务器的模块。通过http模块提供的http.createServer()方法&#…...

静态库与动态库

库是已经写好的、成熟的、可复用的代码。在我们的开发的应用中经常有一些公共代码是需要反复使用的&#xff0c;就把这些代码编译为库文件。库可以简单看成一组目标文件的集合&#xff0c;将这些目标文件经过压缩打包之后形成的一个可执行代码的二进制文件。库有两种&#xff1…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

#Uniapp篇:chrome调试unapp适配

chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器&#xff1a;Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

FFmpeg:Windows系统小白安装及其使用

一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】&#xff0c;注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录&#xff08;即exe所在文件夹&#xff09;加入系统变量…...