提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
关于SDK、库、框架、函数、接口介绍记录
一、SDK
在软件开发中,SDK(Software Development Kit,软件开发工具包) 是一套为特定平台、功能或编程语言提供的“开发工具箱”,核心目的是帮开发者快速对接目标功能、降低开发难度,不用从零实现底层逻辑。
你可以把它理解成:“给开发者的‘半成品工具包’” —— 里面装好了开发所需的核心资源,不用自己造轮子,直接拿过来用就行。
Ⅰ、SDK 里通常包含什么?
一个完整的 SDK 会打包多种资源,覆盖开发全流程需求:
- 核心代码库(Libraries):编译好的二进制文件(比如
.jar、.dll、.so),包含底层功能的实现(比如支付逻辑、地图渲染、音视频编码),开发者不用关心内部原理,直接调用即可。 - API 接口(Application Programming Interface):开发者能直接调用的“函数/方法”(比如
wx.login()微信登录接口、map.showLocation()地图定位接口),是 SDK 对外暴露的“操作入口”。 - 开发工具(Tools):辅助开发的软件,比如编译器、调试器、模拟器(比如 Android SDK 的
adb调试工具、Unity SDK 的游戏编辑器)。 - 示例代码(Sample Code):可直接运行的demo,展示如何使用 SDK 的核心功能(比如“微信分享”的完整代码示例),开发者能直接复制修改。
- 文档(Documentation):使用指南、接口说明、问题排查手册(比如“如何集成 SDK”“接口参数含义”),是开发者的“说明书”。
- 配置文件/证书:对接平台所需的授权文件(比如第三方登录的
AppID、支付的密钥证书)。
Ⅱ、SDK 的核心作用:为什么开发者离不开它?
- 避免重复造轮子:比如开发 App 时需要“微信登录”,不用自己对接微信的底层协议,直接用微信开放平台提供的 SDK,调用1-2个接口就能实现。
- 降低技术门槛:复杂功能(如音视频通话、地图导航、支付对接)的底层逻辑(协议、编码、加密)非常复杂,SDK 已经封装好,开发者不用懂底层,只需关注业务逻辑。
- 保证兼容性和稳定性:SDK 由官方或专业团队维护,会适配不同系统(iOS/Android/Windows)、不同版本,避免开发者自己实现时出现兼容问题。
- 快速对接第三方功能:大部分第三方服务(支付、登录、推送、统计)都会提供 SDK,比如集成支付宝支付、百度地图、极光推送,都需要接入对应的 SDK。
Ⅲ、常见的 SDK 例子
- 第三方功能 SDK:微信开放平台 SDK(登录/分享/支付)、支付宝 SDK(支付)、百度地图 SDK(定位/导航)、友盟统计 SDK(用户行为统计)。
- 平台开发 SDK:Android SDK(开发 Android 应用)、iOS SDK(开发 iOS 应用)、Unity SDK(开发游戏)、Windows SDK(开发 Windows 桌面应用)。
- 功能型 SDK:FFmpeg SDK(音视频处理)、OpenCV SDK(图像处理)、TensorFlow Lite SDK(移动端 AI 推理)。
Ⅳ、容易混淆:SDK 和 API 的区别?
很多人会把两者搞混,用一句话说清关系:API 是 SDK 的“部分”,SDK 是包含 API 的“完整工具包”:
- API 是“接口”:是 SDK 对外暴露的“调用入口”(比如
wx.share()是微信 SDK 的一个 API)。 - SDK 是“工具包”:除了 API,还包含实现 API 所需的代码库、工具、文档、示例等。
举个例子:你想给手机装一个“拍照功能”——
- API 就是“拍照按钮”(你只需要按按钮,不用管相机如何成像);
- SDK 就是“完整的相机套件”(包含相机硬件驱动、拍照软件、按钮、使用说明书)。
总结:SDK 是开发者的“得力助手”,通过封装复杂逻辑、提供现成工具,让开发者能更高效、更稳定地实现各种功能,尤其是对接第三方服务或平台时,SDK 是必备工具。
二、SDK、DLL、API 关系
Ⅰ、C++ 场景下 SDK 与 DLL 的关系
1. 先明确两个概念的专业定义
- C++ DLL(动态链接库):是 Windows 平台下的 二进制可执行模块(文件后缀
.dll),通过动态链接机制在程序运行时被加载,核心作用是封装可复用的代码逻辑(函数、类、全局变量),实现代码模块化、解耦和资源共享,编译后仅包含二进制指令和导出表(记录对外暴露的符号)。 - C++ SDK(软件开发工具包):是针对特定功能/平台的 完整开发支撑套件,核心目标是让开发者能基于该套件快速开发兼容目标功能的程序,其组成必然围绕“让开发者能调用核心逻辑”展开,典型包含:
- 核心实现:1个或多个 DLL(封装底层逻辑,是 SDK 的“功能载体”);
- 调用契约:配套头文件(
.h)—— 声明 DLL 中对外暴露的函数、类、宏定义、数据结构(开发者调用的“入口说明”); - 链接依赖:导入库(
.lib)—— 编译期用于链接的“符号索引文件”,让编译器知道 DLL 中导出函数的位置,最终生成的程序运行时依赖 DLL; - 辅助资源:开发文档(接口说明、参数约束、错误码)、示例代码(C++ 可直接编译的调用demo)、配置工具等。
2. 核心关系总结
- DLL 是 SDK 的“核心功能实现组件”,SDK 是包含 DLL 及“使用 DLL 所需全部资源”的超集:
- DLL 仅负责“实现功能”,但单独的 DLL 对开发者无实际使用价值(不知道有哪些可调用函数、参数类型、返回值含义、调用约定);
- SDK 通过“DLL(实现)+ 头文件(调用契约)+ 导入库(编译链接)+ 文档(使用指南)”的组合,解决了“如何调用 DLL”的问题,让开发者无需关心 DLL 内部实现,仅通过头文件和文档即可完成调用。
3. 举例佐证
比如某厂商的“C++ 音视频 SDK”:
- 核心文件:
av_codec.dll(封装编解码逻辑); - 配套文件:
av_codec.h(声明导出函数EncodeFrame(...)、DecodeFrame(...))、av_codec.lib(导入库)、API手册.pdf(说明参数约束); - 开发者的使用流程:包含头文件 → 链接导入库 → 编译生成程序 → 运行时加载
av_codec.dll→ 调用头文件声明的函数。
这里的av_codec.dll是 SDK 的一部分,而 SDK 是“DLL + 配套资源”的完整套件。
Ⅱ、API 接口与函数的关系
1. 专业定义
- 接口(API,Application Programming Interface):是 功能调用的契约/规范,核心定义“能做什么、输入是什么、输出是什么、约束是什么”,不包含具体实现逻辑,仅明确调用方与实现方的交互规则(比如“传入两个int,返回它们的和”)。
- 函数(Function):是 C++ 中的 具体实现单元,是一段包含特定逻辑的可执行代码块,有明确的函数名、参数列表、返回值类型和函数体(
{ ... }内的代码),负责实现接口定义的契约。
2. 核心关系
- 接口是“抽象契约”,函数是“接口的具体实现形式”:
- 接口定义“要提供什么功能”(比如“提供两数相加的功能”),函数通过具体代码实现该功能(比如
int Add(int a, int b) { return a + b; }); - 一个接口可以对应多个函数实现(比如“排序接口”可通过
QuickSort(...)、BubbleSort(...)两个函数实现),但所有实现必须符合接口的契约(输入输出一致); - 反之,并非所有函数都是接口:仅当函数被“对外暴露,作为调用方与实现方的交互入口”时,才成为接口;内部函数(仅模块内调用,不对外声明)不属于接口。
- 接口定义“要提供什么功能”(比如“提供两数相加的功能”),函数通过具体代码实现该功能(比如
3. C++ 场景的补充说明
C++ 没有原生的 interface 关键字(Java/C# 有),其接口通常以两种形式存在:
- 普通接口:通过 头文件中的函数声明 定义(比如 DLL 配套头文件中的
int Add(int a, int b);),对应的函数体在 DLL 中实现; - 抽象接口:通过 纯虚函数抽象类 定义(比如
class ISort { public: virtual void Sort(int[] arr) = 0; }),子类实现纯虚函数即为接口实现。
Ⅲ、DLL 中的导出函数是不是接口?
结论:是,但特指“对外公开的导出函数”(需满足两个核心条件)
1. 导出函数的本质
C++ 中 DLL 的导出函数,是通过 __declspec(dllexport) 关键字(或模块定义文件 .def)声明,被编译器标记为“可被外部进程调用”的函数,其信息会被写入 DLL 的 导出表(记录函数名、入口地址、参数签名等),是 DLL 对外暴露功能的“物理入口”。
2. 成为接口的关键条件
导出函数要成为“API 接口”,必须满足:
- 具备 公开的调用契约:通过 SDK 头文件以
__declspec(dllimport)声明(比如__declspec(dllimport) int Add(int a, int b);),明确告知调用方函数的名称、参数类型、返回值、调用约定(__cdecl/__stdcall等); - 具备 公开的使用说明:被纳入 SDK 文档,明确其功能、参数约束(比如“a 和 b 不能超过 int 最大值”)、错误码含义等,成为调用方可依赖的“稳定契约”。
3. 反例:不构成接口的导出函数
如果 DLL 中的导出函数仅用于 内部模块交互(比如 DLL A 导出函数供 DLL B 调用,但不对外公开头文件和文档),则它只是“内部导出函数”,不属于面向开发者的 API 接口——因为调用方无法获取调用契约,无法安全调用。
4. 总结
- 逻辑等价:对外公开的 DLL 导出函数 = C++ 场景下的 API 接口(物理入口 + 公开契约);
- 核心区别:“导出函数”是编译层面的“可调用符号”,“接口”是设计层面的“功能契约”,当导出函数被赋予公开契约时,就成为了接口。
- SDK 与 DLL:DLL 是 SDK 的核心功能载体(实现层),SDK 是“DLL + 头文件 + 导入库 + 文档”的完整开发套件(支撑层),无 SDK 仅 DLL 无法有效开发;
- API 与函数:API 是抽象契约(定义“能做什么”),函数是具体实现(解决“怎么做”),对外暴露的函数是 API 的主要实现形式;
- DLL 导出函数与接口:对外公开(有头文件声明+文档说明)的 DLL 导出函数,就是 C++ 中的 API 接口;未公开的内部导出函数不算。
5. 关于 SDK 的补充
你的“dll合集+头文件+lib导入库+说明书”抓住了SDK的核心组成,但可以更严谨一点:
- 不一定是“合集”:SDK 可能只包含一个 DLL(而非多个),核心是“DLL(功能实现)+ 让开发者能调用DLL的配套资源”;
- 补充“辅助资源”:除了核心的 DLL、头文件(
.h)、导入库(.lib)、文档(说明书),部分SDK可能还包含少量辅助工具(比如配置脚本、调试工具),但这些是附加项,核心还是你说的四类。
简化后精准表述:C++ SDK 的核心是“DLL(功能载体)+ 头文件(调用声明)+ 导入库(编译链接)+ 文档(使用说明)”的组合,目的是让开发者能直接调用DLL的功能。
6. 关于接口的补充
你的“接口就是对外导出的函数”在C++ DLL场景下基本成立,但要明确两个前提:
- 接口的本质是“对外公开的调用契约”,DLL的“导出函数”是这个契约的“物理载体”——只有当导出函数同时满足“有头文件声明(告知调用规则)+ 有文档说明(告知功能/约束)”时,才是完整的API接口;
- 接口不局限于“普通导出函数”:C++中还有“纯虚函数抽象类”这种接口形式(比如
class ICalculator { virtual int Add(int a, int b) = 0; }),但在DLL开发中,“对外导出的函数”是最常见、最直接的接口形式。
简化后精准表述:C++ DLL场景下,接口最主要的形式就是“对外公开的导出函数”(需配合头文件+文档明确调用规则)。
7. 最终精准简化结论
- SDK:核心是「DLL + 头文件 + lib导入库 + 文档」,帮你直接调用DLL功能的完整开发套件;
- 接口:C++ DLL场景中,本质是“对外公开的调用契约”,最常见的形式就是“有头文件+文档支持的DLL导出函数”。
三、框架与库
在 C++ 开发中,框架(Framework)和库(Library)的核心区别并非“是否有主函数入口”,而是「控制流归属」(谁主导程序执行流程)、「功能边界」(是否提供完整解决方案)和「使用方式」(是“调用”还是“嵌入”)—— 这是专业场景下区分二者的关键,结合你提到的 Qt(框架)和文件读取库(如 Boost.Filesystem、libpng),具体拆解如下:
Ⅰ、先明确两个概念的专业定义
1. 库(Library,简称“库”)
- 定义:是 一组封装好的可复用代码模块(可能是静态库
.lib、动态库.dll,或源码级库),核心作用是提供“单一/聚焦的功能”(比如文件读写、数据加密、图片解码),不干预程序的整体执行流程。 - 本质:是“被动调用的工具集”—— 开发者主导程序的控制流,库仅作为“功能补充”,开发者需要时主动调用库的函数/类,用完即返回,库不影响程序的启动、循环、退出等核心流程。
2. 框架(Framework)
- 定义:是 一套“完整的开发骨架”,不仅提供核心功能模块(如 UI、网络、事件循环),更重要的是定义了程序的「执行流程范式」(比如初始化、事件响应、生命周期管理),开发者需遵循框架的规则,将自己的业务逻辑“嵌入”到框架预设的“插槽”中。
- 本质:是“主动主导的骨架”—— 框架掌握程序的控制流(比如 Qt 的事件循环、MFC 的消息泵),开发者不需要从零设计程序架构,只需按照框架的接口规范,实现特定的回调函数/子类,框架会在合适的时机自动调用这些代码。
Ⅱ、核心区别:用“控制反转(IoC)”和实际例子说透
1. 最关键区别:控制流是谁的?(核心中的核心)
-
库:开发者主导控制流(你调用库)
你决定“什么时候用库、怎么用库”,库不参与程序的整体流程设计。
例子:用Boost.Filesystem库读取 XML 文件
流程完全由你控制:- 你写主函数
main(),定义程序启动逻辑; - 当需要读取文件时,主动调用
boost::filesystem::read_file(...); - 库执行读取逻辑后返回结果,你继续主导后续流程(比如解析文件内容、处理数据);
- 库从头到尾不干预你的程序启动、循环、退出,只是“按需调用的工具”。
- 你写主函数
-
框架:框架主导控制流(框架调用你)
框架已经定义好了程序的“骨架流程”,你只需要填充“血肉”(业务逻辑),框架会在预设节点自动调用你的代码。
例子:用 Qt 写一个带按钮的窗口程序
流程由 Qt 主导:- 你写的
main()里,必须初始化 Qt 的QApplication(框架的核心组件),然后调用app.exec()启动「事件循环」(框架的控制核心); - 你不需要自己写“监听鼠标点击”的逻辑——Qt 框架会自动捕获系统事件(比如按钮点击);
- 你只需按照 Qt 的规范,重写
QPushButton的clicked()信号对应的槽函数(比如on_btn_click()),框架在检测到点击事件时,会自动调用你的槽函数; - 程序的生命周期(窗口创建、显示、销毁)、事件分发逻辑,都由 Qt 框架控制,你无法脱离这个骨架单独编写程序。
- 你写的
2. 其他关键区别(表格对比,C++ 场景聚焦)
| 对比维度 | 库(Library) | 框架(Framework) |
|---|---|---|
| 控制流归属 | 开发者主导(主动调用库) | 框架主导(框架调用开发者代码) |
| 功能边界 | 单一/聚焦功能(如文件读写、加密、解码) | 完整解决方案(如 UI、网络、数据库、生命周期管理) |
| 使用方式 | 直接调用函数/实例化类(无强制规范) | 遵循框架接口,实现回调/子类(强规范) |
| 依赖关系 | 弱依赖(可替换,比如换文件库不影响程序架构) | 强依赖(程序架构绑定框架,替换成本极高) |
| 扩展方式 | 调用 API 扩展功能 | 通过框架提供的“插件/接口”扩展功能 |
| 典型例子(C++) | Boost.Filesystem、libpng、OpenCV(基础功能) | Qt、MFC、Unreal Engine(游戏框架) |
Ⅲ、回应你的疑问:“框架有自己的主函数入口吗?”
结论:没有—— 主函数(main())依然是开发者编写的,但框架会通过“核心组件初始化”和“事件循环”接管控制流。
- 以 Qt 为例:你的程序必须有
main(),但main()里的核心逻辑是“接入框架”,而非“主导流程”:#include <QApplication> #include <QPushButton> int main(int argc, char *argv[]) { QApplication app(argc, argv); // 初始化 Qt 框架核心组件 QPushButton btn("点击我"); btn.show(); // 调用 Qt 框架的窗口显示接口 return app.exec(); // 启动 Qt 事件循环(框架接管控制流) }app.exec()之后,程序的控制流就交给了 Qt 框架:开发者写的main()至此“暂停”,后续所有逻辑(事件捕获、信号槽触发、窗口刷新)都由框架主导,直到用户关闭窗口,exec()才返回,main()结束。
- 而库的场景中,
main()完全由你主导,库不会接管控制流:#include <boost/filesystem.hpp> #include <iostream> int main() { boost::filesystem::path file_path("test.xml"); if (boost::filesystem::exists(file_path)) { // 主动调用库函数 std::cout << "文件存在" << std::endl; } // 后续流程继续由你控制,库不干预 return 0; }
Ⅳ、C++ 场景下的精准总结
- 库:是“被动调用的工具”,提供单一功能,开发者主导所有流程,想什么时候用就什么时候调用,替换成本低;
- 框架:是“主动主导的骨架”,提供完整的程序架构和执行流程,开发者必须遵循框架规则,将业务逻辑嵌入框架的“插槽”中,框架在合适时机自动调用你的代码;
- 核心区别一句话:库是“你调用它”,框架是“它调用你”(控制反转),而非“是否有主函数入口”。
结合你的工作场景:
- 读取文件用的
Boost.Filesystem是库:你主导“什么时候读、读什么、读完做什么”,库只负责“读”这个单一功能; - Qt 是框架:它帮你搞定了 UI 渲染、事件处理、网络通信等复杂架构,你只需要专注于“按钮点击后做什么业务逻辑”,其余流程都由 Qt 接管。

1万+

被折叠的 条评论
为什么被折叠?



