SDK、库、框架、函数、接口

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

关于SDK、库、框架、函数、接口介绍记录


一、SDK

在软件开发中,SDK(Software Development Kit,软件开发工具包) 是一套为特定平台、功能或编程语言提供的“开发工具箱”,核心目的是帮开发者快速对接目标功能、降低开发难度,不用从零实现底层逻辑。

你可以把它理解成:“给开发者的‘半成品工具包’” —— 里面装好了开发所需的核心资源,不用自己造轮子,直接拿过来用就行。

Ⅰ、SDK 里通常包含什么?

一个完整的 SDK 会打包多种资源,覆盖开发全流程需求:

  1. 核心代码库(Libraries):编译好的二进制文件(比如 .jar.dll.so),包含底层功能的实现(比如支付逻辑、地图渲染、音视频编码),开发者不用关心内部原理,直接调用即可。
  2. API 接口(Application Programming Interface):开发者能直接调用的“函数/方法”(比如 wx.login() 微信登录接口、map.showLocation() 地图定位接口),是 SDK 对外暴露的“操作入口”。
  3. 开发工具(Tools):辅助开发的软件,比如编译器、调试器、模拟器(比如 Android SDK 的 adb 调试工具、Unity SDK 的游戏编辑器)。
  4. 示例代码(Sample Code):可直接运行的demo,展示如何使用 SDK 的核心功能(比如“微信分享”的完整代码示例),开发者能直接复制修改。
  5. 文档(Documentation):使用指南、接口说明、问题排查手册(比如“如何集成 SDK”“接口参数含义”),是开发者的“说明书”。
  6. 配置文件/证书:对接平台所需的授权文件(比如第三方登录的 AppID、支付的密钥证书)。

Ⅱ、SDK 的核心作用:为什么开发者离不开它?

  1. 避免重复造轮子:比如开发 App 时需要“微信登录”,不用自己对接微信的底层协议,直接用微信开放平台提供的 SDK,调用1-2个接口就能实现。
  2. 降低技术门槛:复杂功能(如音视频通话、地图导航、支付对接)的底层逻辑(协议、编码、加密)非常复杂,SDK 已经封装好,开发者不用懂底层,只需关注业务逻辑。
  3. 保证兼容性和稳定性:SDK 由官方或专业团队维护,会适配不同系统(iOS/Android/Windows)、不同版本,避免开发者自己实现时出现兼容问题。
  4. 快速对接第三方功能:大部分第三方服务(支付、登录、推送、统计)都会提供 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 接口(物理入口 + 公开契约);
  • 核心区别:“导出函数”是编译层面的“可调用符号”,“接口”是设计层面的“功能契约”,当导出函数被赋予公开契约时,就成为了接口。
  1. SDK 与 DLL:DLL 是 SDK 的核心功能载体(实现层),SDK 是“DLL + 头文件 + 导入库 + 文档”的完整开发套件(支撑层),无 SDK 仅 DLL 无法有效开发;
  2. API 与函数:API 是抽象契约(定义“能做什么”),函数是具体实现(解决“怎么做”),对外暴露的函数是 API 的主要实现形式;
  3. 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 文件
    流程完全由你控制:

    1. 你写主函数 main(),定义程序启动逻辑;
    2. 当需要读取文件时,主动调用 boost::filesystem::read_file(...)
    3. 库执行读取逻辑后返回结果,你继续主导后续流程(比如解析文件内容、处理数据);
    4. 库从头到尾不干预你的程序启动、循环、退出,只是“按需调用的工具”。
  • 框架:框架主导控制流(框架调用你)
    框架已经定义好了程序的“骨架流程”,你只需要填充“血肉”(业务逻辑),框架会在预设节点自动调用你的代码。
    例子:用 Qt 写一个带按钮的窗口程序
    流程由 Qt 主导:

    1. 你写的 main() 里,必须初始化 Qt 的 QApplication(框架的核心组件),然后调用 app.exec() 启动「事件循环」(框架的控制核心);
    2. 你不需要自己写“监听鼠标点击”的逻辑——Qt 框架会自动捕获系统事件(比如按钮点击);
    3. 你只需按照 Qt 的规范,重写 QPushButtonclicked() 信号对应的槽函数(比如 on_btn_click()),框架在检测到点击事件时,会自动调用你的槽函数;
    4. 程序的生命周期(窗口创建、显示、销毁)、事件分发逻辑,都由 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++ 场景下的精准总结

  1. :是“被动调用的工具”,提供单一功能,开发者主导所有流程,想什么时候用就什么时候调用,替换成本低;
  2. 框架:是“主动主导的骨架”,提供完整的程序架构和执行流程,开发者必须遵循框架规则,将业务逻辑嵌入框架的“插槽”中,框架在合适时机自动调用你的代码;
  3. 核心区别一句话:库是“你调用它”,框架是“它调用你”(控制反转),而非“是否有主函数入口”。

结合你的工作场景:

  • 读取文件用的 Boost.Filesystem 是库:你主导“什么时候读、读什么、读完做什么”,库只负责“读”这个单一功能;
  • Qt 是框架:它帮你搞定了 UI 渲染、事件处理、网络通信等复杂架构,你只需要专注于“按钮点击后做什么业务逻辑”,其余流程都由 Qt 接管。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值