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

C C++ 如何编写库级接口

初级代码游戏的专栏介绍与文章目录-CSDN博客

我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。

这些代码大部分以Linux为目标但部分代码是纯C++的,可以在任何平台上使用。

源码指引:github源码指引_初级代码游戏的博客-CSDN博客


     一般我们会用虚函数或者会提供头文件就算会编写“接口”了。
    不过接口有很多级别,提供头文件(没有约束的任意头文件)是最低的级别——这本来就是C/C++最基本的编码方法,通常只能在同一项目里,换个项目会遇到很多问题。
    使用虚函数是高一点的级别,虚函数能够隐藏实现、提供动态类型,非常适合不同代码模块的协作。
    如果要想编写一个通用的库,提供给别人使用,那么还得满足众多约束条件,才能实现一个真正能让别人用的库。

目录

1 头文件必须是纯粹的(充分且必要)

原则:尽可能减少名字冲突的可能性

2 使用纯粹的C接口和C++虚函数

原则:屏蔽实现依赖,仅仅通过接口交互

3 默认隐藏所有符号

4 把普通类包装为接口

5 兼容性考虑



1 头文件必须是纯粹的(充分且必要)


    头文件不能包含多余的东西,也必须是完整的,不能有缺失。
    出于编程方便,我们经常把include放在尽可能高的位置,比如一个公共的“common.h”或者“Util.h”或者“projectbase.h”之类的头文件里面,这样就不需要在每个源码文件里包含,省时省力(但是浪费编译器)。
    但是作为库,我们应该只提供库接口,不应该包含多余的东西。包含只跟实现有关的头文件也不行,因为接口头文件里面用到的也必须同时提供,不然没法使用。
    包含接口实现用到的标准头文件看起来没什么问题,标准头文件大家都有嘛,多数情形问题不大,但是如果别人系统上可能真的没有呢?或者要用不同的版本呢?或者包含了这个就会跟别的冲突呢?没必要制造麻烦。
    有些零零碎碎的东西,比如实现用到的一个全局变量,是不是可以放在接口头文件里面?大家都方便嘛。不是的。头文件暴露的任何不必要的东西都会给使用者造成困扰,头文件包含的任何一个名字都可能和使用者自己的代码冲突。

原则:尽可能减少名字冲突的可能性

2 使用纯粹的C接口和C++虚函数


    完全使用C接口是最理想的,配合extern "C"指定为操作系统的API标准,可以供任何语言使用(任何语言都有调用系统API的办法)。
    如果使用C++暴露接口,那么应该遵循纯接口规则,只使用函数和虚函数,不使用数据成员。(我坚持认为interface没有进入C++标准是个悲剧)
    C++类的内存布局是和编译器有关的,也和一些参数有关,比如为了对齐插入的填充字节,所以类里面如果包含数据成员,很可能带来麻烦。
    任何数据成员的存在都是不必要的。内部的数据成员应该通过get/set暴露,这种做法给内部升级提供了可能,否则等于限制内部实现再也无法甩开这个数据成员。
    任何私有方法的存在都是多余的。
    不能有内联函数,内联函数实际上是重新编译的,根本不会用到库里面的(库里面很可能根本没有)。基于前面的约束,类里面没有数据成员,那么内联函数又能做些什么呢?
    函数参数只使用基本数据类型,使用任何类都必须额外提供头文件,包含数据成员的类又存在潜在问题,所以不建议参数使用类。

原则:屏蔽实现依赖,仅仅通过接口交互

3 默认隐藏所有符号


    这仍然是基于减少名字冲突这个原则。
    windows上默认就是隐藏的,必须显示导出符号。
    linux上则默认是导出的,这意味着存在巨大的冲突可能性,所以要查编译器手册,改为默认隐藏所有符号,再手动导出必要的符号。

4 把普通类包装为接口


    把一个带有数据成员和私有成员的类包装为接口通常需要写一个包装类。
    所有暴露的函数都要写一个函数来包装,这有点繁琐但是是必须的。
    接口类通常自带一个创建自身的函数,一般叫instance()、Create类名()什么的。

5 兼容性考虑


    头文件里最好不要有受编译器影响的东西,比如char,究竟是有符号还是无符号,如果是提供源码重新编译这可能不是问题,但是如果提供的是编译好的库,还是要斟酌一下的。
    如果自己写库要同时编译成32位和64位,也要考虑是否需要使用int32_t这种明确指定的长度的类型。
 


(这里是文档结束)

相关文章:

C C++ 如何编写库级接口

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 源码指引:github源…...

安装TDengine数据库3.3版本和TDengine数据库可视化管理工具

安装TDengine数据库3.3版本和TDengine数据库可视化管理工具 一、下载安装包二、解压安装包三、部署四、启动服务五、进入数据库六、创建数据库、表和往表中插入数据七、测试 TDengine 性能八、使用数据库九、查询数据十、TDengine数据库可视化界面 一、下载安装包 TDengine-cl…...

详解CAS

一、CAS是什么? CAS是Java中Unsafe类里面的一个方法,是Compare and Swap的缩写,中文翻译成比较并交换,主要功能是能够去保证在多线程的环境下对于共享变量修改的一个原子性,实现并发算法时常用到的一种技术。它包含三…...

《环境感知方案:探索未来智能世界的关键技术》

《环境感知方案:探索未来智能世界的关键技术》 一、环境感知方案的研究现状(一)机器人领域的环境感知(二)农业领域的环境感知(三)智能网联汽车领域的环境感知 二、先进的环境感知技术&#xff0…...

Android 编译时出现Android resource linking failed.without required default value.

错误信息如下: Execution failed for task :app:processDebugResources. > A failure occurred while executing com.android.build.gradle.internal.res.LinkApplicationAndroidResourcesTask$TaskAction> Android resource linking failedwarn: removing r…...

golang ws升级为wss

首先需要一份openssl证书 1.安装openssl windows安装openssl 的下载地址在 https://slproweb.com/products/Win32OpenSSL.html 无脑点安装就行,记得最后安装完成的页面取消勾选 安装完成后记得配置环境变量 2.生成证书 openssl req -x509 -days 36500 -nodes …...

FFMPEG录屏(17)--- 使用 DwmRegisterThumbnail 捕获指定窗口图像数据

使用 DwmRegisterThumbnail 捕获指定窗口图像数据 在 Windows 平台上,捕获指定窗口的图像数据可以通过多种方法实现,其中一种高效的方法是使用 [DwmRegisterThumbnail] 本文将介绍如何使用 [DwmRegisterThumbnail] 捕获窗口图像数据,并提供一…...

点亮一个LED(51)

目录 1.LED介绍 2.硬件电路 3.程序设计 3.1.点亮一颗LED 3.2.LED闪烁 3.3.LED流水灯实现 1.LED介绍 发光二极管也具有二极管普遍的特性单向导电性,有阳极和阴极之分 ,上图左侧式插件式LED ,长的引脚是阳极;左侧是贴片式的带…...

Flink窗口分配器WindowAssigner

前言 Flink 数据流经过 keyBy 分组后,下一步就是 WindowAssigner。 WindowAssigner 定义了 stream 中的元素如何被分发到各个窗口,元素可以被分发到一个或多个窗口中,Flink 内置了常用的窗口分配器,包括:tumbling wi…...

【Tinymce】富文本编辑器在vue项目中的使用;引入付费格式刷,上传视频、图片

引言 富文本编辑器有很多,对比了一下,还是决定用tinymce(号称宇宙最强),基础的插件确实好用,但是一些更好用的插件,比如格式刷等都是高级版(付费),当然也有人…...

Java实现简单的5阶m序列密钥生成

选择5阶本原多项式:x^5 x^2 1,初始值为{1,0,0,1,1},易得,递推公式为:ak ak-5 ⊕ ak-2 ,其中k≥5。于是可以写出下面这段代码: class BitsEncode {public static void main(String[] args) {//初始化数组…...

013_django基于大数据的高血压人群分析系统2024_dcb7986h_055

目录 系统展示 开发背景 代码实现 项目案例 获取源码 博主介绍:CodeMentor毕业设计领航者、全网关注者30W群落,InfoQ特邀专栏作家、技术博客领航者、InfoQ新星培育计划导师、Web开发领域杰出贡献者,博客领航之星、开发者头条/腾讯云/AW…...

OpenCV高级图形用户界面(21)暂停程序执行并等待用户按键输入函数waitKey()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 等待按键 该函数 waitKey 在 delay≤0 时无限等待按键事件,或者在 delay 为正数时等待 delay 毫秒。由于操作系统在切换线程时有最小…...

其他css的用途

1.animation-fill-mode: backwards; //避免了在动画开始前元素的突然显现,动画必要。 2.用rem响应式字体大小,可以在html样式定义font-size?(例10px,62.5%(100%是16px))。然后样式就可以用rem代替px。 3.color: transparent;: 这行代码将文…...

json路径 [‘a‘].b.c[0].d[‘1‘].f,具体代表什么意思

JSON路径是一种用于从JSON对象中提取数据的表达方式。你给出的路径 [a].b.c.d[1].f 代表了如何逐层访问JSON对象中的数据。让我们逐步解析这个路径: ‌[a]‌: 表示访问JSON对象的根元素中键为 a 的值。使用方括号 [] 通常意味着这个键是一个字符串&#…...

等保测评:如何进行有效的安全合规性审查

等保测评(信息安全等级保护测评)是一项至关重要的安全合规性审查工作,旨在帮助组织保障信息系统的安全性、合规性,有效应对安全风险,提升整体安全防护水平。下面将从等保测评的流程、意义、应用场景,以及实…...

FFmpeg 4.3 音视频-多路H265监控录放C++开发二 : 18.04ubuntu安装,linux 下build ffmpeg 4.3 源码 并测试

测试环境 ubuntu 18.04 64 位,安装vmware and ubuntu 安装后调整 分辨率: 让windows 可以和 linux 互相复制黏贴 sudo apt-get autoremove open-vm-tools sudo apt-get update sudo apt-get install open-vm-tools-desktop 一直Y reboot 依赖安装 sud…...

将两张图片的不同标记出来

差异过于细微,阈值设置不当:您的差异可能是颜色或位置的微小变化,当前的阈值和处理方式可能不足以检测到这些细微差异。 图像配准不够精确:由于两张图片内容高度相似,特征点匹配可能存在误差,导致图像对齐…...

HarmonyOS开发(State模型)

一、State模型概述 FA(Feature Ability)模型:从API 7开始支持的模型,已经不再主推。 Stage模型:从API 9开始新增的模型,是目前主推且会长期演进的模型。在该模型中,由于提供了AbilityStage、Wi…...

在 WPF 中使用 OpenTK:从入门到进阶

一、引言 WPF(Windows Presentation Foundation)是微软推出的用于创建丰富的桌面应用程序用户界面的框架。OpenTK 则为我们提供了强大的图形处理能力,包括 3D 图形渲染、数学计算等功能。将两者结合起来,可以在 WPF 应用程序中实…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

【AI学习】三、AI算法中的向量

在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具

第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...