Linux上位机开发实战(编写API库)

news2025/3/25 14:39:19

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

        我们自己编写linux上位机软件的时候,尽量都是通过框架+库的形式来开发。这就是所谓的低耦合,高内聚。相似的功能、模块和算法,都可以做成一个静态库,或者是动态库。实际操作中,客户一般喜欢设计为动态库。因为相比较动态库而言,静态库需要重新编译,比较麻烦。而动态库,即使有bug,直接替换dll、so文件即可。

1、API库的构成

        提供给客户的API库,从技术上说一般包含了head头文件、so动态库文件即可。另外,从版权保护的角度来说,通常还包含一个license文件,或者是一个usb key。

2、编程语言

        通常来讲,接口都会是c语言开发的,实现部分可以是c,也可以是c++。这样,即使客户是用其他语言开发的,也只需要把库文件简单做一个语言封装,这样就可以比较容易地转到其他编程语言,比如说c#、java、python、js、ruby、perl、go等等。

3、基本原则

        对外输出的动态库,最重要的原则,就是只提供必要的信息,隐藏实现的细节。对外提供的函数,一般都是包括在header头文件里面。中间如果涉及到复杂的结构体,最好也是用void*表示。实际开发库的时候,我们自己习惯用cpp开发,但是发布给客户,一定要用extern "C"包装一下。

4、文档部分

        除了技术的部分,详细的使用文档也是必不可少的。每一个api是什么意思,对应的参数是什么,都需要详细地告诉用户。用户可能也不一定看,但是交付的时候,还是有必要提供的。和代码版本一样,文档部分,我们也要做好版本管理。

5、demo代码

        前面说过,客户拿到API库之后,未必会认真查看文档。这种情况下,把范例做好,就可以极大地降低我们开发的工作量。另外,客户的行业、开发水平、人员构成也是千差万别,所以example需要尽量简单,api的命名也尽量简单一些。功能最好直接一点,比如生成的二维码、条形码、人脸识别的位置和概率、车牌识别位置和内容,这种是最合适的。

6、举例说明

        假设我们需要写一个图像处理的库。这个时候就需要把实现和接口分开。这里说的分开,并不是说头文件和cpp文件分开,而是说api接口,和类实现分开。

        假设实现是这样的,

// header file
#ifndef IMG_PROGRAME_FRAME_H
#define IMG_PROGRAME_FRAME_H

class ImgProgrameFrame
{
public:
	ImgProgrameFrame();
	~ImgProgrameFrame();

	bool Initialize(bool isRGB, int width, int height);
	int GetWidth();
	int GetHeight();
	bool GetResult(void* p_img, void* p_result);

private:
	void InnerProcess(); // other function defined here

};
#endif

// cpp file
ImgProgrameFrame::ImgProgrameFrame() {}
ImgProgrameFrame::~ImgProgrameFrame() {}
bool ImgProgrameFrame::Initialize(bool, int, int) { return false; }
int ImgProgrameFrame::GetWidth() { return 0; }
int ImgProgrameFrame::GetHeight() { return 0; }
bool ImgProgrameFrame::GetResult(void*, void*) { return true; }
void ImgProgrameFrame::InnerProcess() {}; // other function implementation

        但是给客户的API接口肯定不是这样,上面的实现只能我们自己看到。不可能把class的细节都给客户,

// header file
#ifndef IMG_PROGRAME_FRAME_API_H
#define IMG_PROGRAME_FRAME_API_H

void Initialize(bool isRGB, int width, int height);
int GetWidth();
int GetHeight();
bool GetResult(void* img,void* param);
#endif

// cpp file
static class ImgProgrameFrame _gFrame;
void Initialize(bool isRGB, int width, int height)
{
	_gFrame.Initialize(isRGB, width, height);
}

int GetWidth() { return _gFrame.GetWidth(); }
int GetHight() { return _gFrame.GetHeight(); }
bool GetResult(void* img, void* result) { return _gFrame.GetResult(img, result); }

        和具体的实现相比较,对外提供的接口都比较简洁。类中的变量、私有函数、部分public函数都会做一个提取之后,再转交给客户。或者说,我们提供给客户的部分,只是客户愿意付费的那部分。这是比较方便、也比较合理的一个做法。

        当然如果需要并发处理,一般就会生成一个动态的ImgProgrameFrame对象,通过void*给客户,每次客户使用的时候再传进来即可。类似于这样,

// header file
#ifndef IMG_PROGRAME_FRAME_API_H
#define IMG_PROGRAME_FRAME_API_H

void* InitializeObject(bool isRGB, int width, int height);
int GetWidth(void* p);
int GetHeight(void* p);
bool GetResult(void*p, void* img, void* result);
#endif

// cpp file
void* InitializeObject(bool isRGB, int width, int height)
{
	ImgProgrameFrame* p = new ImgProgrameFrame();
	p->Initialize(isRGB, width, height);
	return (void*)p;
}

int GetWidth(void* p)
{
	return ((ImgProgrameFrame*)(p))->GetWidth();
}

int GetHeight(void* p)
{
	return ((ImgProgrameFrame*)(p))->GetHeight();
}

bool GetResult(void*p, void* img, void* result)
{
	return ((ImgProgrameFrame*)(p))->GetResult(img, result);
}

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

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

相关文章

器件功耗模型原理

器件功耗模型原理 谷歌提供了一套通用的器件耗电模型和配置方案,先对器件进行耗电因子拆解,建立器件功耗模型,得到一个器件耗电的计算公式。通过运行时统计器件的使用数据,代入功耗模型,就可以计算出器件的功耗。例如…

拥抱成长型思维:解锁持续进步的人生密码

我强烈推荐4本可以改变命运的经典著作: 《寿康宝鉴》在线阅读白话文《欲海回狂》在线阅读白话文《阴律无情》在线阅读白话文《了凡四训》在线阅读白话文 一、什么是成长型思维? 成长型思维(Growth Mindset)由斯坦福大学心理学家卡…

Ubuntu上查看GPU使用情况并释放内存

先用nvidia-smi查看GPU当前使用情况 再用fuser 命令查找对应显卡上占用 GPU 的进程 最后查到了用kill -9强制杀掉进程(PID)即可

解决思科交换机无法访问局域网外设备

问题背景 有时,我们需要远程连接来管理一台思科交换机,例如使用SSH协议。然而交换机运作在链路层,这就需要交换机有一个网络层地址,来接纳基于IP协议的远程访问请求。于是,我们依靠设置一个带有IP地址的交换机虚拟接口…

什么是张量计算

以下是对张量计算的详细介绍,结合数学、物理学及计算机科学等多领域视角: 一、张量的基本定义与性质 1. 张量的数学定义 张量是向量空间及其对偶空间的笛卡尔积上的多重线性映射,可视为多维数组或几何对象。其核心特征在于: 坐…

【1】Java 零基础入门学习(小白专用)

【1】Java 零基础入门学习 📚博客主页:代码探秘者 ✨专栏:《JavaSe从入门到精通》 其他更新ing… ❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更新的动力❤️ 🙏作者水…

[c语言日寄]枚举类型

【作者主页】siy2333 【专栏介绍】⌈c语言日寄⌋:这是一个专注于C语言刷题的专栏,精选题目,搭配详细题解、拓展算法。从基础语法到复杂算法,题目涉及的知识点全面覆盖,助力你系统提升。无论你是初学者,还是…

【氧化镓】​​​​掺杂在β-Ga2O3材料中引入的深能级缺陷

1. 引言 1.1 β-Ga2O3材料的特性与应用前景 β-Ga2O3作为一种新型的宽禁带半导体材料,具有约4.6-4.8 eV的宽带隙、高击穿场强(约8 MV/cm)和优异的热稳定性,适用于高功率和射频电子器件。其独特的物理特性使其在高电压、高频率以及高功率应用场景中具有巨大的潜力。例如,…

仅靠prompt,Agent难以自救

Alexander的观点很明确:未来 AI 智能体的发展方向还得是模型本身,而不是工作流(Work Flow)。还拿目前很火的 Manus 作为案例:他认为像 Manus 这样基于「预先编排好的提示词与工具路径」构成的工作流智能体,…

Playwright + MCP:用AI对话重新定义浏览器自动化,效率提升300%!

一、引言:自动化测试的“瓶颈”与MCP的革新 传统自动化测试依赖开发者手动编写脚本,不仅耗时且容易因页面动态变化失效。例如,一个简单的登录流程可能需要开发者手动定位元素、处理等待逻辑,甚至反复调试超时问题。而MCP&#xf…

计算机操作系统(五) 前趋图和程序执行与进程的描述(附带图谱表格更好对比理解))

计算机操作系统(五) 前趋图和程序执行与进程的描述 前言一、前趋图和程序执行1.1前趋图1.2程序的顺序执行1.3程序的并发执行 二、进程的描述2.1进程的定义与特征2.2进程的基本状态与转换2.3挂起的操作系统和进程的转换2.4进程管理中的数据结构 总结&…

C/C++静态库的理解和制作

1.什么是库 库是写好的现有的,成熟的,可以复用的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。 本质上来说库是⼀种可执行代码的二进制形式,可以被操作系统…

【redis】主从复制:单点问题、配置详解、特点详解

文章目录 单点问题什么是主从复制主从模式能解决的问题并发量有限可用性问题 配置建立复制通过配置文件来指定端口配置主从查看集群结构 断开复制 特点安全性只读传输延迟 单点问题 分布式系统中,涉及到一个非常关键的问题:单点问题 某个服务器程序&…

android......

事件源,就是视图对象,先注册一个监听器,等待用户触发了屏幕,一旦触发会立即产生一个事件源,事件源会生成一个用户点击的触发事件,此刻监听器会立马监听到 ,然后监听器调用回调方法 UI理解 全称用…

常见中间件漏洞(tomcat)

CVE-2017-12615 当在Tomcat的conf(配置目录下)/web.xml配置文件中添加readonly设置为false时,将导致该漏洞产生,(需要允许put请求) , 攻击者可以利用PUT方法通过精心构造的数据包向存在漏洞的服务器里面上传…

计算机网络高频(二)TCP/IP基础

计算机网络高频(二)TCP/IP基础 1.什么是TCP/IP⭐⭐ TCP/IP是一种网络通信协议,它是互联网中最常用的协议之一。TCP/IP有两个基本的协议:TCP(传输控制协议)和IP(互联网协议)。 TCP(Transmission Control Protocol,传输控制协议)是一种可靠的、面向连接的协议。它负…

国际护士节知识竞赛主持稿串词

在这充满火热激情的季节,我们又迎来了5.12国际护士节。让我们首先向辛勤奋战在护理工作一线的全县广大护士姐妹们道一声: (男)让我们再一次以热烈的掌声欢迎他们:预祝各参赛代表队在护理知识竞赛中赛出风格,赛出水平,取得满意的成绩。 (女)…

Elasticsearch:可配置的推理 API 端点分块设置

作者:来自 Elastic Daniel Rubinstein Elasticsearch 开放推理 API 现已支持可配置的分块,以便在文档摄取时处理语义文本字段。 Elasticsearch 推理 API 允许用户利用各种提供商的机器学习模型执行推理操作。其中一个常见用例是在索引中支持用于语义搜索…

数据结构之链表(双链表)

目录 一、双向带头循环链表 概念 二、哨兵位的头节点 优点: 头节点的初始化 三、带头双向链表的实现 1.双链表的销毁 2.双链表的打印 3.双链表的尾插和头插 尾插: 头插: 4.双链表的尾删和头删 尾删: 头删: …

uniapp从 vue2 项目迁移到 vue3流程

以下是必须为迁移到 vue3 进行调整的要点,以便 vue2 项目可以在 vue3 上正常运行。 1. 在index.js中创建应用程序实例 // Before - Vue 2 import Vue from vue import App from ./App // with no need for vue3 Vue.config.productionTip false // vue3 is no lon…